在下拉菜单包装器组件中渲染这些<a>排序按钮?

时间:2019-10-29 19:01:05

标签: javascript reactjs

我正在为网站的移动视图制作一个下拉菜单包装器组件。我需要当前被映射为元素的6个排序按钮的下拉菜单。我尝试了各种策略,例如使用CSS构建下拉菜单,使用按钮等。每次尝试在下拉菜单中将此组件的输出呈现为子级时,我一无所获或[object Object]。

这是呈现排序按钮的代码

// DatasetSort GraphQL fields
const sortFields = [
  'created',
  'name',
  'uploader',
  'stars',
  'downloads',
  'subscriptions',
]

export const SortField = ({ field, queryVariables, refetch }) => {
  const fieldValue =
    field in queryVariables.orderBy && queryVariables.orderBy[field]
  let icon
  if (fieldValue) {
    if (fieldValue === 'ascending') {
      icon = <i className="fa fa-sort-asc" />
    } else {
      icon = <i className="fa fa-sort-desc" />
    }
  }
  const sortBy = () => {
    const newQueryVariables = { ...queryVariables }
    // Clear existing sorts
    newQueryVariables.orderBy = {}
    // Apply (or toggle) based on previous sort
    newQueryVariables.orderBy[field] =
      queryVariables.orderBy[field] === 'descending'
        ? 'ascending'
        : 'descending'
    refetch(newQueryVariables)
  }
  return (
    <a
      key={field}
      className={fieldValue ? 'btn-sort name active' : 'btn-sort name'}
      onClick={sortBy}>
      <Capitalized>{field}</Capitalized> {icon}
    </a>
  )
}

const DatasetSorter = ({ queryVariables, refetch }) => (
  <>
    {sortFields.map(field => (
      <SortField
        field={field}
        queryVariables={queryVariables}
        refetch={refetch}
        key={field}
      />
    ))}
  </>
)

export default DatasetSorter

在移动设备上时,我有条件地呈现此下拉列表,而不是DatasetSorter。我需要DatasetSorter中的按钮才能在下拉菜单中呈现为选项,所以我将其作为子项传递给了

class DropdownWrapper extends React.Component {
  constructor(props) {
    super(props)

    this.state = { value: 'Sort By' }
  }

  onChange(e) {
    this.setState({
      value: e.target.value,
    })
  }

  render() {
    return (
      <div>
        <Select value={this.state.value} onChange={this.onChange.bind(this)}>
          {this.props.children}
        </Select>
      </div>
    )
  }
}

下拉列表的呈现方式如下:

<DropdownWrapper >
    <DatasetSorter refetch={refetch} queryVariables={queryVariables} />
</DropdownWrapper>

我尝试过将孩子包装在选项标签中。我尝试有条件地将DatasetSorter中的排序“按钮”呈现为不同类型的元素。我确定我在这里遗漏了一些明显的东西,但我不知道是什么。

1 个答案:

答案 0 :(得分:0)

我可以通过有条件地将元素呈现为

  • 标签,然后将它们注入配置为容纳它们的下拉列表(即li标签)中来弄清楚这一点。

    下拉菜单(使用样式化的组件)

    const Dropdown = styled.label`
        display: inline-block;
        position: relative;
        font-weight: lighter;
        font-size: 18px;
        font-family: "Open Sans", sans-serif;
        float: right;
        padding: 0 20px;
        height: auto;
        margin: 10px 0px 0px;
    `
    
    const Menu = styled.div`
        display: inline-block;
        background: #007c92;
        color: #fff;
        border-radius: 2px;
        border: 0;
        box-shadow: inset 0 0 1px 1px rgba(0, 0, 0, 0.1);
        padding: 10px 30px 10px 20px;
        cursor: pointer;
        white-space: nowrap;
    `
    const List = styled.ul`
        position: absolute;
        top: 100%;
        padding: 0;
        margin: 2px 0 0 0;
        box-shadow: 0 0 6px 0 rgba(0,0,0,0.1);
        background-color: #ffffff;
        list-style-type: none;
        z-index: 99999;
    
        li {
            padding: 10px 20px;
            cursor: pointer;
            white-space: nowrap;
          }
    `
    
    const Input = styled.input`
        display: none;
        + .dd-menu {
            display: none;
          } 
        :checked + .dd-menu {
        display: block;
        } 
    
    `
    
    
    class DropdownWrapper extends React.Component {
        constructor(props) {
            super(props)
        }
    
      render() {
        return (
            <div>
                <Dropdown className="dropdown">
                    <Menu className="dd-button">
                        Sort By:
                    </Menu>
                    <Input type="checkbox" className="dd-input" />
                    <List className="dd-menu">
                        {this.props.children} 
                    </List>       
                </Dropdown>
          </div>
        )
      }
    }
    

    条件排序:

    if (!isMobile) {
        return (
          <a
            key={field}
            className={fieldValue ? 'btn-sort name active' : 'btn-sort name'}
            onClick={sortBy}>
            <Capitalized>{field}</Capitalized> {icon}
          </a>
        )
      } else if (isMobile) {
        return (
            <li
            key={field}
            className={fieldValue ? 'btn-sort name active' : 'btn-sort name'}
            onClick={sortBy}>
            <Capitalized>{field}</Capitalized> {icon}
            </li>
        )
      }
    }