2

I am trying to use React Beautiful DND library to drag and drop lists in a todo application but I keep getting these three errors in my console.

Error 1:

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `Droppable`.

Error 2:

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `Draggable`.

Error 3:

Invariant failed: provided.innerRef has not been provided with a HTMLElement.

The following is a snippet of the my code. I also made use of styled components:

import React from 'react';
import styled from 'styled-components';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';


function App() {
  ...

  return (
    <>
        <DragDropContext>
          <Droppable>
            {(provided) => (
              <TodoList {...provided.droppableProps} ref={provided.innerRef}>
                {
                  shadowTodoItems.map((todoItem, index) => (
                    <Draggable key={todoItem.id} draggableId={todoItem.id} index={index}>
                      {(provided) => (
                        <div>
                          <TodoListItem ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps} />
                        </div>
                        
                      )}
                    </Draggable>
                  ))
                }
                {provided.placeholder}
              </TodoList>
            )}
          </Droppable>
        </DragDropContext>
    </>
  );
}

How do I fix these errors please? Thank you.

Idris
  • 558
  • 7
  • 29

2 Answers2

6

As the error message states,

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Invariant failed: provided.innerRef has not been provided with a HTMLElement.

Add a div and provide ref.

 <DragDropContext>
          <Droppable>
            {(provided) => (
              <div  ref={provided.innerRef}>
                <TodoList {...provided.droppableProps}>
                    {
                    shadowTodoItems.map((todoItem, index) => (
                        <Draggable key={todoItem.id} draggableId={todoItem.id} index={index}>
                        {(provided) => (
                            <div ref={provided.innerRef}>
                            <TodoListItem {...provided.draggableProps} {...provided.dragHandleProps} />
                            </div>
                            
                        )}
                        </Draggable>
                    ))
                    }
                    {provided.placeholder}
                </TodoList>
              </div>
            )}
          </Droppable>
        </DragDropContext>

OR

Consider wrapping your component with React.forwardRef

const TodoList = React.forwardRef((props, ref) => {
  return <div ref={ref}>...</div>
});
PsyGik
  • 3,535
  • 1
  • 27
  • 44
3

As mentioned, "Function components cannot be given refs.", meaning you need to implement a ref forwarding for your custom function components, for example:

const TodoList = React.forwardRef(ref, props => {
  // Forward the ref to inner wrapper, whatever the implemention is
  return <div ref={ref}></div>
});

See related docs.

Dennis Vash
  • 50,196
  • 9
  • 100
  • 118