【问题标题】:React DnD useDrop is not using the current state when the method is called调用方法时 React DnD useDrop 未使用当前状态
【发布时间】:2022-06-16 08:05:49
【问题描述】:

我正在尝试创建一个具有拖放项目功能的待办事项应用程序。我正在使用 React DND 并且到目前为止一切正常,但是当一个新项目添加到列表中时,我意识到在 useDrop 中的“drop”方法中调用的 函数只会使用页面首次加载时的状态。 没有其他组件有这个问题,当我尝试简单的 onClick 来检查同一组件的状态时,也会记录正确的状态。其他组件(例如插入新任务的组件)根本没有问题,这只发生在使用 React DND 的组件上。我还检查了 chrome 中的 react 开发工具,并且可以确认状态也在更新。
在“drop”中调用的函数是从两个组件向上传递的,我尝试使用的状态也在该组件中。 任何帮助将不胜感激。谢谢。

export const ToDo = ({
  status,
  todoText,
  todoID,
  deleteTodo,
  updateTodoStatus,
  resortList,
}: TodoProps) => {
  const [, drag] = useDrag(() => ({
    type: 'TODO_DRAG',
    item: { todoID, todoText },
  }));

  const [, drop] = useDrop(() => ({
    accept: 'TODO_DRAG',
    drop: (droppedTodo: dropAndDropItem) => {
      console.log('dropping');
      if (todoID === droppedTodo.todoID) return;
      resortList(todoID, droppedTodo.todoID);
    },
  }));

  return (
    <li ref={drop} onClick={() => resortList(1, 2)}>
      <div ref={drag}>
        <label htmlFor="Change Todo Status">
          <input
            type="checkbox"
            checked={status}
            onChange={() => updateTodoStatus(todoID)}
          />
        </label>
        <p>{todoText}</p>
        <button onClick={() => deleteTodo(todoID)}>X</button>
      </div>
    </li>
  );
};

【问题讨论】:

    标签: reactjs react-dnd


    【解决方案1】:

    您好,过去两天我也遇到了同样的问题。试试这个来解决你的问题。

    const [, drop] = useDrop(() => ({
    accept: 'TODO_DRAG',
    drop: (droppedTodo: dropAndDropItem) => {
      console.log('dropping');
      if (todoID === droppedTodo.todoID) return;
      resortList(todoID, droppedTodo.todoID);
    },}),[todoID]);
    

    没有 [todoID] drop 不会“看到”更新状态,但我现在不知道为什么。

    【讨论】:

      【解决方案2】:

      我花了几天时间尝试使用与您的结构相似的结构来解决这个问题(父状态和函数被传递给具有 dnd 的子状态)。

      通过我自己的测试,似乎我因 DnD 操作而更改的任何状态对象都需要在 usedrop 的 deps 数组中列出(usedrag 我不确定,但我会怀疑)。

      就我而言,我在父组件中做了这样的事情:

      let dndDependencies = [state1, state2, ...]
      ...
      <ChildComponentWithDnD dndDependencies = {dndDependencies}/>
      

      我将它传递给子组件以作为依赖项插入到 useDrop 操作。

      所以在你的情况下,它看起来像:

      const [, drop] = useDrop(() => ({
      accept: 'TODO_DRAG',
      drop: (droppedTodo: dropAndDropItem) => {
        console.log('dropping');
        if (todoID === droppedTodo.todoID) return;
        resortList(todoID, droppedTodo.todoID);
      },
      }), props.dndDependencies);
      

      我不完全确定这是否同样适用于 useDrag,但在我的整个应用程序中将其添加到我的 useDrops 似乎已经解决了问题。

      我不是特别喜欢我的所有子组件都需要传递所有由 dnd 操作更改的父状态,但它确实解决了问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-19
        • 1970-01-01
        • 1970-01-01
        • 2023-02-16
        • 2021-06-09
        • 2021-07-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多