React / Material-UI 检测列表中的最后一个 ListItem

ama*_*may 5 reactjs material-ui

我正在使用 Material-ui 和 React。我有一个如下所示的列表视图:

<List>
    <Subheader>List Title</Subheader>
    <ListItem primaryText="Option One" />
    <Divider />
    <ListItem primaryText="Option Two" />
    <Divider />
    <ListItem primaryText="Option Three" />
</List>
Run Code Online (Sandbox Code Playgroud)

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

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

nib*_*iba 4

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

const allOptions = [
  { text: "Option 1", permission: 1 },
  { text: "Option 2", permission: 2 },
  { text: "Option 3", permission: 4 }
]
Run Code Online (Sandbox Code Playgroud)

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

const permittedOptions = listItems.filter(checkPermission) 
Run Code Online (Sandbox Code Playgroud)

使用地图创建列表项

const listItems = permittedOptions.map(option => <ListeItem text={option.text} />)
Run Code Online (Sandbox Code Playgroud)

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

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

最后渲染它

<List>
    <Subheader>List Title</Subheader>
    {listItemsWithDividers}
</List>
Run Code Online (Sandbox Code Playgroud)