React / Material-UI 检测列表中的最后一个 ListItem
React / Material-UI detect last ListItem in List
我正在使用 material-ui 和 React。我有一个如下所示的列表视图:
<List>
<Subheader>List Title</Subheader>
<ListItem primaryText="Option One" />
<Divider />
<ListItem primaryText="Option Two" />
<Divider />
<ListItem primaryText="Option Three" />
</List>
每个项目之间有一个分隔符,但 none 在第一个项目之前或最后一个项目之后。到目前为止一切顺利。
我刚刚实现了一个简单的包装器,它根据用户权限呈现或不呈现列表项。所以它看起来像这样:
<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 组件将用户权限与指定权限进行比较,returns 子组件或 null。这一切都有效,但如果未呈现该选项,显然会保留分隔线。
我可以将分隔线与 ListItem 一起包装在 Restricted 组件中,ListItem 在大多数情况下呈现我想要的内容,但如果未呈现最后一项,它会在底部留下一个分隔线。我需要的是一种表示如果这是列表中的最后一项则不要呈现分隔线的方式。
目前我的计划是以编程方式生成一个可显示列表项数组,然后使用适当的分隔符在循环中呈现它。但这将意味着我将不得不在每个使用它的组件中使用决策逻辑,而不是单个包装器。感觉不对。
我是否错过了 React/material-ui 的某些方面,这将使我能够以更优雅的方式实现我想要的目标?
我提出以下解决方案。首先将您的列表表示移动到变量
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>
一个更具成本效益的方法看起来像这样
<div>
<List>
{items.map((item) => (
<div key={item.id}>
<ListItem>
<ListItemText primary={item.name} />
</ListItem>
{item.id !== items.length ? <Divider /> : null}
</div>
))}
</List>
</div>
{items.data.map((item, index) => (
<ListItem button key={index} divider={index < items.length - 1}>
...
</ListItem>
)})
我正在使用 material-ui 和 React。我有一个如下所示的列表视图:
<List>
<Subheader>List Title</Subheader>
<ListItem primaryText="Option One" />
<Divider />
<ListItem primaryText="Option Two" />
<Divider />
<ListItem primaryText="Option Three" />
</List>
每个项目之间有一个分隔符,但 none 在第一个项目之前或最后一个项目之后。到目前为止一切顺利。
我刚刚实现了一个简单的包装器,它根据用户权限呈现或不呈现列表项。所以它看起来像这样:
<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 组件将用户权限与指定权限进行比较,returns 子组件或 null。这一切都有效,但如果未呈现该选项,显然会保留分隔线。
我可以将分隔线与 ListItem 一起包装在 Restricted 组件中,ListItem 在大多数情况下呈现我想要的内容,但如果未呈现最后一项,它会在底部留下一个分隔线。我需要的是一种表示如果这是列表中的最后一项则不要呈现分隔线的方式。
目前我的计划是以编程方式生成一个可显示列表项数组,然后使用适当的分隔符在循环中呈现它。但这将意味着我将不得不在每个使用它的组件中使用决策逻辑,而不是单个包装器。感觉不对。
我是否错过了 React/material-ui 的某些方面,这将使我能够以更优雅的方式实现我想要的目标?
我提出以下解决方案。首先将您的列表表示移动到变量
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>
一个更具成本效益的方法看起来像这样
<div>
<List>
{items.map((item) => (
<div key={item.id}>
<ListItem>
<ListItemText primary={item.name} />
</ListItem>
{item.id !== items.length ? <Divider /> : null}
</div>
))}
</List>
</div>
{items.data.map((item, index) => (
<ListItem button key={index} divider={index < items.length - 1}>
...
</ListItem>
)})