【问题标题】:React: Edit and Delete from a pop-up menu on a list itemReact:从列表项的弹出菜单中编辑和删除
【发布时间】:2021-03-28 07:02:42
【问题描述】:

我有一个列表容器组件,它是父级。它映射出列表行。在列表行组件(即子项)上,每个项目都有一个用于切换弹出菜单的按钮,该菜单有一个用于编辑的按钮和一个用于删除的按钮。菜单本身是列表行的兄弟,因为如果我将它包含在列表行组件中,每一行都会呈现一个菜单,并且在切换时,它们都会堆叠在一起。编辑和删除按钮可以切换表单进行编辑,或者直接删除项目。

我目前拥有的是:

// 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,但在调用handledItemDelete 时出现未定义。

我尝试在子级上使用 ref 从父级获取 ID,结果也未定义。

我想不出如何使用 useEffect 来检查 handleMenuOpen 参数的变化。

我没有想法。有谁知道问题是什么以及如何解决?

【问题讨论】:

  • 你每次都在传递 null,你为什么要在函数周围创建一个额外的包装器?
  • 请提供minimal reproducible example,因为您的代码看起来不是很清楚。
  • 我正在构建一个最小的可重现示例,当我完成时,它正在工作。问题是当删除操作创建者期待一个项目时,我正在输入一个 id。奇怪的是,当我在整个过程中将ID放入console.log时,它会返回null,直到我调度。

标签: javascript reactjs material-ui


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我之前也遇到过同样的问题。我认为您应该处理子组件中的弹出窗口切换,所以像这样。

    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>
        )
    }
    

    【讨论】:

      【解决方案3】:

      我假设您正在执行某个循环来渲染 List 组件中的每个 List Row

      假设所有项目都在您循环的项目数组中:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-23
        • 2019-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多