React:在弹出式菜单上编辑和删除列表项

4
我有一个列表容器组件,作为父级元素,它映射出列表行。在每个列表行组件中,即子组件中,每个项目都有一个按钮来切换弹出菜单,该菜单包括编辑和删除按钮。由于如果将菜单包含在列表行组件中,则每一行都会呈现一个菜单,当进行切换操作时,它们会全部叠放在一起,因此菜单本身是列表行的同级组件。编辑和删除按钮分别切换到用于编辑的表单或直接删除该项。
// Parent / Container

  const [itemID, setItemID] = useState(null);

  const handleMenuOpen = (id) => (e) => {
    setAnchorEl(e.currentTarget); // for menu placement
    setItemID(id);
  };

  const handleItemDelete = () => {
    dispatch(deleteItem(itemID));
  };

<List>
  <ListRow handleMenuOpen={handleMenuOpen} />
  <Menu handleItemDelete={handleItemDelete}  itemID={itemID} />
</List>;


// List Row

<Button onClick={handleMenuOpen(item.id)} />;

// Menu

<MenuItem onClick={() => handleModalOpen(itemID)} />;

<MenuItem onClick={() => handleItemDelete()} />;
编辑按钮正常工作,但无论我如何尝试,都不能从列表项的onClick中让setItemID起作用。它总是作为null的初始值出现。我在函数参数中记录了ID,但setState钩子没有起作用。 我尝试将useState放在列表项上,并通过useContext传递ID,但在调用handleItemDelete时出现未定义。 我尝试使用子代上的ref来从父级获取ID,结果也是未定义的。 我想不到如何使用useEffect来检查handleMenuOpen参数的更改。 我没办法了,请问有人知道问题出在哪里,以及如何解决吗?

2
你每次都传递 null,为什么要在函数周围创建额外的包装器? - EugenSunic
请提供一个最小可复现示例,因为你的代码看起来不是很清晰。 - nromaniv
我正在构建一个最小可重现的示例,当我完成时,它可以工作。问题是在删除操作创建器期望项目时,我输入了一个ID。仍然很奇怪的是,当我在整个过程中将ID放入console.log中时,直到我调度它才返回null。 - hellocng
3个回答

0

我假设你正在使用某个循环来渲染列表组件中的每一行列表行。

假设所有项目都在一个名为items的数组中,你可以通过循环遍历它:

{items.map(item => (
  <ListRow handleMenuOpen={handleMenuOpen}/>
  <Menu handleItemDelete={handleItemDelete} item={item} />
)}

现在在菜单容器或组件中,您将拥有该项并将其传递给菜单项


0

你应该只传递 handleMenuOpen 函数并依赖于所选元素,然后将其 ID 存储在 itemID 变量中。

const handleMenuOpen = (e) => {
    setAnchorEl(e.currentTarget); // for menu placement
    setItemID(e.currentTarget.id);
};
  
  
<MenuItem onClick={handleMenuOpen} />;

0
我之前也遇到过同样的问题。我认为你应该在子组件中处理弹出窗口的切换,就像这样做。
function Parent() {
    function handleDelete(item) {
        deleteFunction(item.id)
    }

    return (
        <div>
            {[].map((item, index) => {
                return (
                    <ListRowItem key={index} handleDelete={handleDelete} item={item} />
                )
            })}
        </div>
    )
}

function ListRowItem({handleDelete, item}) {
    const [isMenuOpen, setIsMenuOpen] = useState(false)
    const [isModelVisible, setIsModalVisible] = useState(false)

    return (
        <div>
            <Button onClick={isMenuOpen === true ? () => setIsMenuOpen(true) : () => setIsMenuOpen(false)} />
            {isModelVisible === true ? <ModalItem /> :null}
            {isMenuOpen === true ? 
                <div>
                    <MenuItem onClick={() => setIsModalVisible(true)} />
                    <MenuItem onClick={() => handleDelete(item.id)} />
                </div>
            : null}
        </div>
    )
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,