反应漂亮的 DND - 我得到“无法找到带有 id: 1 的可拖动”

Wil*_*iam 12 javascript reactjs react-beautiful-dnd

在下面的代码中,UI 呈现两个“Column”组件,每列包含两个称为“Tasks”的可拖动元素。当用户在列之间拖动“任务”时,代码会起作用 -直到某一点。当用户持续拖动任务组件时,最终它们将停止拖动并且用户收到一个错误消息:

无法找到带有 ID 的可拖动对象:X

我不知道为什么会发生这种情况,也不知道如何解决。

注意:我假设库的工作方式是拖动元素时需要重新排序和更新onDragEnd函数中的状态。

这是我的代码:

应用程序.js

import React,{useState} from 'react';
import {DragDropContext} from 'react-beautiful-dnd';
import helper from './helper_functions'

import Column from './Components/Column';

function App() {

  let initialState =   [
    {
      groupName:"Today",
      tasks:[
          {id:"1", title:"Test-1"},
          {id:"2", title:"Test-2"}
        ]
    },
    {
      groupName:"Tomorrow", 
      tasks:[
          {id:"3", title:"Test-3"},
          {id:"4", title:"Test-4"}
        ]
    },
  ]


  const [taskList, setTasks] = useState(initialState)

  function onDragEnd(val){

     let result = helper.reorder(val.source,val.destination,taskList);
     setTasks(result)
  }

  return (
    <DragDropContext onDragEnd={onDragEnd}>
       <Column droppableId="Today" list= {taskList[0].tasks} type="TASK"/>
       <Column droppableId ="Tomorrow" list = {taskList[1].tasks} type="TASK"/>
       <div> context hello world </div>
    </DragDropContext>
  );
}

export default App;
Run Code Online (Sandbox Code Playgroud)

源代码/helper_functions

export default {
    reorder:function(source,destination,taskDataArr){

     let taskData = [...taskDataArr]

 //     //_____________________________________________________________Source data
    let sourceGroupIndex = taskData.findIndex((val, index) => {                // iterate and find "Today" (or other) index in list data
        return val.groupName === source.droppableId
    });

    let draggedTask = taskData[sourceGroupIndex].tasks.find((val, index) => {  // Get specific task object based on index
        return source.index === index
    }); // dragged object

    let sourceListCopyWithElementRemoved = taskData[sourceGroupIndex].tasks.filter((val, index) => {
        return index !== source.index // removes dragged element from array
    });

    // //__________________________________________________________________Destination data

    let destinationGroupIndex = taskData.findIndex((val, index) => {  // iterate and find "Tomorrow" (or other) index in list data
        return val.groupName === destination.droppableId
    });


    taskData[destinationGroupIndex].tasks.splice(destination.index, 0, draggedTask); // insert dragged item to new place
    taskData[sourceGroupIndex].tasks = sourceListCopyWithElementRemoved

    return taskData

  }


}
Run Code Online (Sandbox Code Playgroud)

源代码/组件/列

import React from 'react';
import {Droppable} from 'react-beautiful-dnd';
import Task from "../../Components/Task"

function Column(props){
   const { classes, droppableId, list, type} = props;

   let style = {
    backgroundColor:"orange",
    height:"300px",
    width:"400px",
    margin:"100px"

   }

   console.log(list)



    return (

       <Droppable droppableId = {droppableId} type={type}>
       {provided => (

          <div {...provided.droppableProps} ref={provided.innerRef} style={style}>
          <h2>{droppableId}</h2>

            {list.map((val,index)=>{
               return <Task id={val.id} key={index} index={index} title={val.title}/>
            })}

           {provided.placeholder}
          </div>
        )
       }
       </Droppable>
    )
}

export default Column
Run Code Online (Sandbox Code Playgroud)

源代码/组件/任务

import React from 'react';
import {Draggable} from 'react-beautiful-dnd';



function Task(props){
    const { classes, id, index,title } = props;
    let style = {
    backgroundColor:"red",


   }

    return (
       <Draggable draggableId ={id} index={index} type="TASK">

         {(provided) => (
            <div
              ref={provided.innerRef}
              {...provided.draggableProps}
              {...provided.dragHandleProps}
            >
              <h4 style={style}>{title}</h4>
            </div>
        )}

       </Draggable>
    )
}

export default Task
Run Code Online (Sandbox Code Playgroud)

小智 83

如果您在 React 18 上遇到此错误

Unable to find draggable with id: 
Run Code Online (Sandbox Code Playgroud)

尝试删除 StrictMode

  • 借调了。这对我有用,但我想保持严格模式——这里发生了什么? (9认同)
  • 为什么严格模式会影响这种行为? (7认同)
  • 这里有一个直接替换解决了这个问题:https://github.com/hello-pangea/dnd (7认同)
  • 不要替换整个库或关闭严格模式,而是尝试使用此解决方案:https://github.com/atlassian/react-beautiful-dnd/issues/2350#issuecomment-1318179729 (6认同)
  • @MarcinHubert我相信fork是一个足够好的解决方案,它保证有自己的答案。如果是的话我会投票。 (2认同)

bam*_*mse 43

您的代码存在一些问题:

  1. 错误 Unable to find draggable with id: X

Column您用作index任务键的组件中。我认为这就是导致此错误的原因

使用任务idas key, inColumn可以消除这个错误。

  1. reorder 有一些问题:
    • 将任务放在同一列中时它会删除任务
    • 当任务被删除到列之外时引发错误

我对你的代码很感兴趣,并尝试了另一种重新排序的方法。如果您添加更多列,这种重新排序方式可能会派上用场 - 仍有改进的空间。

希望能帮助到你!

  • 使用与“draggableId”“prop”相同的“ID”而不是“key”道具的“index”解决了我的问题 (9认同)

Avi*_*ash 14

我遇到了类似的问题,我正在通过多个可拖动进行映射,并且错过了关键道具,将关键添加到可拖动为我解决了这个问题

{tasks.map((t, index) => (
  <Draggable
    draggableId={t._id}
    index={index}
    key={t._id} >
     ....
  </Draggable>
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我为我的“Draggable”包装器添加了“key={task.id}”,并为我的“Droppable”包装器添加了“key={column.id}”,它开箱即用! (2认同)

小智 13

对于错误:

无法找到 ID 为 X 的可拖动对象

  1. 删除 React js 中的严格模式。
  2. 如果您使用 Next.js,您可以在next.config.js文件中找到严格模式

对于错误:

不变失败:Draggable[id: 1]: 无法找到拖动手柄执行以下操作

{process.browser && (
        <section>
          <DragDropContext onDragEnd={onDragEnd}>
                     //Your code with droppable and draggable
           </DragDropContext>
        </section>
)}
Run Code Online (Sandbox Code Playgroud)

相关问题


nDi*_*viD 11

不是针对这种情况,而是针对每一个人 -provided.draggableProps不检查provided.dropableProps

 <Draggable draggableId ={id} index={index} type="TASK">

         {(provided) => (
            <div
              ref={provided.innerRef}
              {...provided.draggableProps}
              {...provided.dragHandleProps}
            >
              <h4 style={style}>{title}</h4>
            </div>
        )}
</Draggable>
Run Code Online (Sandbox Code Playgroud)

RBD 尝试通过提供的.draggableProps 查找节点。缺少这个道具会出错:Unable to find draggable with id: X


小智 8

删除 <React.StrictMode> 为我解决了这个问题。


kis*_*aru 7

我遇到了同样的问题,但是以下步骤对我有帮助

步骤1:

draggableId should be string, not an integer 
Run Code Online (Sandbox Code Playgroud)

根据https://github.com/atlassian/react-beautiful-dnd/issues/1512

第2步:

如果您刚刚学习过 EggHead 教程,那么这可能会错过。尝试添加最上面答案中提到的关键属性

<Draggable key={item.id} draggableId={item.id.toString()} index={index} >
Run Code Online (Sandbox Code Playgroud)


Bip*_*lab 5

如果您仍然遇到此问题,有一个简单的解决方案适合您。只需<React.StrictMode>index.js.


che*_*ist 5

该库不再维护。我切换到叉子:

https://github.com/hello-pangea/dnd

所有问题都得到了解决。