34

In the code below the UI renders two "Column" components and each column contains two draggable elements called "Tasks". When the user drags a "Task" between columns the code works - up to a point. When the user continuously drags the task components around eventually they will stop dragging and the user gets an error that says:

Unable to find draggable with id: X

I don't know why this happens nor how to fix it.

Note: I am assuming the way the library works is when you drag elements you need to reorder and update your state in the onDragEnd function.

Here is my code:

app.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;

src/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

  }


}

src/Components/Column

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

src/Components/Task

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
William
  • 4,422
  • 17
  • 55
  • 108

17 Answers17

77

There are a few issues with your code:

  1. Error Unable to find draggable with id: X

In the Column component you used index as a key for the tasks. I think this is what causes this error.

Using the task id as key, in Column, makes this error go away.

  1. reorder has some issues:
    • it removes a task when dropped in the same column
    • raises an error when a task is dropped outside the columns

I had a bit of fun with you code and tried another way to reorder. This way of reordering might come in handy if you ever add a more columns - there is still room for improvements.

Hope it helps!

bamse
  • 4,243
  • 18
  • 25
58

If you are getting this error on React 18

Unable to find draggable with id: 

Try removing StrictMode

iamziike
  • 589
  • 3
  • 5
14

Not for this case, but For every one - check provided.draggableProps not 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>

RBD try find node by provided.draggableProps. Missing this props got error: Unable to find draggable with id: X

nDiviD
  • 444
  • 1
  • 4
  • 11
11

I had a similar issue, I was mapping through multiple draggable and had missed the key prop, Adding the key to Draggable fixed the issue for me

{tasks.map((t, index) => (
  <Draggable
    draggableId={t._id}
    index={index}
    key={t._id} >
     ....
  </Draggable>
}
Avinash
  • 1,864
  • 2
  • 21
  • 27
9

For Error:

Unable to find draggable with id: X

  1. Remove Strict mode in React js.
  2. If you are using Next.js you can find the strict mode in next.config.js file

For Error:

Invariant failed: Draggable[id: 1]: Unable to find drag handle do the following

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

Related issue

Zach Jensz
  • 3,650
  • 5
  • 15
  • 30
6

I ran into the same issue however the following steps helps me

Step 1:

draggableId should be string, not an integer 

as per https://github.com/atlassian/react-beautiful-dnd/issues/1512

Step 2:

if you are coming from EggHead tutorial, this might have missed. Try to add a key property as mentioned in the top answer

<Draggable key={item.id} draggableId={item.id.toString()} index={index} >
kishorekumaru
  • 1,500
  • 2
  • 19
  • 33
5

Removing <React.StrictMode> fixed it for me.

uxxi
  • 79
  • 2
  • 4
2

If you still getting this issue, there was a simple solution for you. Just remove <React.StrictMode> from the index.js.

Biplab
  • 71
  • 1
  • 7
1

Try converting the integer value to a string. It'll solve the issue as it solved mine

{tasks.map((t, index) => (
  <Draggable
    draggableId={t._id.toString()}
    index={index}
    key={t._id} >
     ....
  </Draggable>
}
1
  1. There is a YouTube lesson on react-beautiful-dnd. He posted his lesson progress in the Code Sandbox enter link description here You can open it and make sure. But I have on "react": "^18.1.0" does not work and gives an error

    Unable to find draggable with id:X

    And on older versions of react everything also works without errors.Try for example another version of react"^17.0.2"ю It worked for me

  2. Also remember, when installing the react-beautiful-dnd library, were there any dependency conflicts? Maybe you have not established all the connections and because of this it does not work correctly. In any case, as a test, I suggest downloading the code from the lesson and checking in my project whether it works or not. If it works, it means an error in the code, if not, then react-beautiful-dvd does not work correctly

BuGaGa
  • 302
  • 2
  • 9
1

I hope this will help someone. If you are experiencing this even your code is correct. Please check your react version. In react version 18.0, dnd will show unable to find draggable with id warning. Current solution to downgrade to 17 and it works flawlessly. I searched for the solution like remove strict mode, using dynamic import and other things but currently it's related to react 18.

uranium235
  • 81
  • 2
  • 10
1

The library is not being maintained any longer. I switch to the fork:

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

And all issues were resolved.

checklist
  • 12,340
  • 15
  • 58
  • 102
0

Post it here, since this is the top link the Google for the same error.

It might be the case, that you do not render an element with the provided.dragHandleProps

<div>
      {someCondition && (
           <div>
               <DragIndicatorIcon {...provided.dragHandleProps}/>
           </div>
      )}
</div>

In this case move {...provided.dragHandleProps} outside the condition

<div {...provided.dragHandleProps}>
      {someCondition && (
           <div>
               <DragIndicatorIcon {...provided.dragHandleProps}/>
           </div>
      )}
</div>

Found this solution here

0

Resolved this issue by converting draggableId into string

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Oct 02 '22 at 23:17
0

It works with react-beautiful-dnd and React 18 in StrictMode. https://github.com/atlassian/react-beautiful-dnd/issues/2399#issuecomment-1175638194

0

For those who are experiencing the same problem with the @hello-pangea/dnd library, converting the id to string worked for me.

<Draggable key={ticket.id} draggableId={ticket.id.toString()} index={index}>
0

Make sure you have provided - draggableId, key and ref