反应挂钩更新状态问题

时间:2020-06-04 18:22:07

标签: reactjs react-hooks

我的应用程序将“板”的整个状态存储在板组件vie useState中。然后,我映射状态以创建列表。

当我尝试通过axios调用删除列表,然后从状态中拼接该列表时,遇到了问题。不会删除目标列表,而是要删除板的最后一个列表。以下是该问题的快速屏幕录像:https://streamable.com/uarb97

从警报中可以看到,一切都按预期进行。我不明白为什么要拼接错误的列表。这是我的handleDelete函数,它从板组件传递到每个列表组件:

const handleDeleteList = (targetList) => {
        event.preventDefault();
        let newBoard = { ...boardState };

        alert(`DELETING ${JSON.stringify(targetList.title)} FROM INDEX ${newBoard.lists.indexOf(targetList)}`)

        newBoard.lists.splice(newBoard.lists.indexOf(targetList), 1);

        alert(`BOARD WILL NOW HAVE LISTS: ${JSON.stringify(newBoard.lists)}`)

        //setState function
        setBoardState({ ...newBoard });

        console.log("THIS IS THE CURRENT STATE THAT IS BEING MAPPED OVER TO DISPLAY THE LISTS") 
       console.log(boardState.lists)
  };

编辑:我已经将handleDeleteList函数更新为使用setState函数,但是出现了相同的问题:

        updateBoardState(oldBoard => {
          const newBoard = { ...oldBoard }
          newBoard.lists.splice(oldBoard.lists.indexOf(targetList), 1)
          return newBoard
        })

这是渲染问题,还是我缺少明显的东西?

1 个答案:

答案 0 :(得分:1)

问题是:

        updateBoardState(oldBoard => {
          const newBoard = { ...oldBoard }
          newBoard.lists.splice(oldBoard.lists.indexOf(targetList), 1)
          return newBoard
        })

传播oldBoard时,您正在复制lists的浅表副本,这意味着:

newBoard.lists.splice(oldBoard.lists.indexOf(targetList), 1)

突变oldBoard.lists会使React感到困惑。

您可以在模拟此问题的“代码沙箱”中看到此内容:https://codesandbox.io/s/sharp-bush-i4kew尝试删除多个项目,然后您会发现它变得越来越不正确。


如果您复制lists并在其上进行拼接,然后构建newBoard,则不会突变oldBoard

updateBoardState(oldBoard => {
        const lists = oldBoard.lists.slice();
        lists.splice(oldBoard.lists.indexOf(targetList), 1);
        return { ...oldBoard, lists };
      });

同样,这是具有工作逻辑的相同代码沙箱:https://codesandbox.io/s/confident-mcnulty-h7378