在我的组件中,我有一个Table
来自一些自定义对象数组的生成行。在上一个TableCell
我想要一个图标按钮,点按即可打开Menu
并执行一些MenuItem
操作(编辑和删除)。这是我的代码:
{folders.map(folder => {
return (
<TableRow key={folder.id} >
<TableCell>{folder.name}</TableCell>
<TableCell>
<IconButton
onClick={this.handleFolderActionClick}>
<MoreHoriz />
</IconButton>
<Menu onClose={this.handleFolderActionClose} >
<MenuItem onClick={event => {onEditFolder(event, folder)}}>
<ListItemIcon>
<Edit />
</ListItemIcon>
<ListItemText inset primary="Edit" />
</MenuItem>
<MenuItem onClick={{event => onDeleteFolder(event, folder)}}>
<ListItemIcon>
<Delete />
</ListItemIcon>
<ListItemText inset primary="Delete" />
</MenuItem>
</Menu>
</TableCell>
</TableRow>
);
})}
onClick
事件始终传递数组中的最后一个文件夹元素,而不是映射到该特定TableRow
的文件夹元素。
我已经读过MenuItem
onClick
事件不应该以这种方式使用,但我没有任何其他想法如何解决我的具体问题。我打开任何建议。如何将对象从外部地图函数传递到onClick
的{{1}}事件?
编辑: Sandbox example
答案 0 :(得分:1)
您可以尝试使用 currying 来避免内联菜单项处理程序并使其更具可读性(并避免可能与语法相关的错误,我相信您有这些错误)。您可以像这样定义处理程序:
onEditFolder = folder => event => {
// edit click handler
}
onDeleteFolder = folder => event => {
// delete click handler
}
然后在渲染中使用它们(在folders.map
循环内),如下所示:
<Menu onClose={this.handleFolderActionClose}>
<MenuItem onClick={this.onEditFolder(folder)}>
<ListItemIcon>
<Edit />
</ListItemIcon>
<ListItemText inset primary="Edit" />
</MenuItem>
<MenuItem onClick={this.onDeleteFolder(folder)}>
<ListItemIcon>
<Delete />
</ListItemIcon>
<ListItemText inset primary="Delete" />
</MenuItem>
</Menu>
您可以这样做,因为onEditFolder(folder)
根据其定义返回一个期望事件的函数。与onDeleteFolder(folder)
相同。
注意:我添加了this
关键字作为两个函数的前缀,假设它们是在使用它们的同一组件中定义的。如果您将它们作为道具传递,请相应地进行修改。
<强>后续强>: 该错误与映射无关,但是由两个菜单依赖于相同的布尔值来切换打开或关闭,导致最后一个菜单显示,无论单击哪个项目。
我通过在状态中创建menus
数组来更正此问题,其中长度设置为列表大小,并且所有值都初始化为false
(这在componentDidMount
中完成生命周期方法)。菜单打开&amp;更新了close和close处理程序以传递列表项的索引,并相应地将menus
数组中的值更新为true
或false
。每个open
组件的Menu
属性设置为menus
数组中的相应条目,以便根据相应的值显示/隐藏菜单。
最后,两个Menu
组件都具有相同的id
,我也对其进行了更正。