【问题标题】:React / Material-UI detect last ListItem in ListReact / Material-UI 检测 List 中的最后一个 ListItem
【发布时间】:2017-07-27 22:23:48
【问题描述】:

我正在将 Material-ui 与 React 一起使用。我有一个看起来像这样的列表视图:

<List>
    <Subheader>List Title</Subheader>
    <ListItem primaryText="Option One" />
    <Divider />
    <ListItem primaryText="Option Two" />
    <Divider />
    <ListItem primaryText="Option Three" />
</List>

每个项目之间有一个分隔符,但在第一项之前或最后一项之后没有。到目前为止一切顺利。

我刚刚实现了一个简单的包装器,它根据用户权限呈现或不呈现列表项。所以它看起来像这样:

<List>
    <Subheader>List Title</Subheader>
    <Restricted permission={1}>
        <ListItem primaryText="Option One" />
    </Restricted>
    <Divider />
    <Restricted permission={2}>
        <ListItem primaryText="Option Two" />
    </Restricted>
    <Divider />
    <Restricted permission={4}>
        <ListItem primaryText="Option Three" />
    </Restricted>
</List>

Restricted 组件将用户权限与指定权限进行比较,并返回子组件或 null。这一切都有效,但如果未呈现选项,显然会保留分隔符。

我可以将分隔线与 ListItem 一起包装在 Restricted 组件中,在大多数情况下它会呈现我想要的内容,但如果最后一项没有呈现,它会在底部留下一个分隔线。我需要的是一种说法,如果这是列表中的最后一项,则不要渲染分隔线。

目前我的计划是以编程方式生成一组可显示的列表项,然后使用适当的分隔符将其呈现在循环中。但这意味着我将不得不在每个使用它的组件中使用决策逻辑,而不是使用单个包装器。感觉不对。

我是否遗漏了 React/material-ui 的某些方面,可以让我以更优雅的方式实现我想要的?

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    我提出以下解决方案。首先将您的列表表示移动到变量

    const allOptions = [
      { text: "Option 1", permission: 1 },
      { text: "Option 2", permission: 2 },
      { text: "Option 3", permission: 4 }
    ]
    

    然后使用过滤器只获取允许的选项

    const permittedOptions = listItems.filter(checkPermission) 
    

    使用地图创建列表项

    const listItems = permittedOptions.map(option => <ListeItem text={option.text} />)
    

    现在仅当有下一个和上一个列表项时才放置分隔符

    const listItemsWithDividers = [];
    listItems.forEach((item, index) => {
      listItemsWithDividers.push(item)
      if (listItems[index + 1] !== undefined) {
         listItemsWithDividers.push(<Divider />)
      }
    })
    

    最后渲染它

    <List>
        <Subheader>List Title</Subheader>
        {listItemsWithDividers}
    </List>
    

    【讨论】:

    • 谢谢。问了这个问题后,我在等待答案时重新审视了它,并提出了类似的代码,除了我将 放在除第一个之外的每个项目之前。
    【解决方案2】:

    更具成本效益的方法看起来像这样

    <div>
          <List>
            {items.map((item) => (
              <div key={item.id}>
                <ListItem>
                  <ListItemText primary={item.name} />
                </ListItem>
                {item.id !== items.length ? <Divider /> : null}
              </div>
            ))}
          </List>
        </div>
    

    【讨论】:

      【解决方案3】:
      {items.data.map((item, index) => (
      <ListItem button key={index} divider={index < items.length - 1}>
      ...
      </ListItem>
      )})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-08
        • 1970-01-01
        • 2017-04-29
        • 2017-10-03
        • 1970-01-01
        • 2019-07-03
        相关资源
        最近更新 更多