NextJS集成react-beautiful-dnd报错:provided.innerRef未传入HTMLElement
React-beautiful-dnd在Next.js中报错:provided.innerRef未绑定到HTMLElement
问题描述
在纯React环境中正常运行的垂直排序列表功能,切换到Next.js后出现如下报错:
next-dev.js?3515:20 react-beautiful-dndA setup problem was encountered.> Invariant failed: provided.innerRef has not been provided with a HTMLElement.You can find a guide on using the innerRef callback functions at:https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/guides/using-inner-ref.md👷 This is a development only message. It will be removed in production builds.
已按照官方指南将ref={provided.innerRef}绑定到DOM元素而非组件,但问题仍未解决。相关代码及配置如下:
1. Index.js
import dynamic from 'next/dynamic'; import React, { useState } from 'react'; import { DragDropContext } from 'react-beautiful-dnd'; const Column = dynamic(() => import('../src/Column'), { ssr: false }); const initialData = { tasks: [ { id: 1, content: 'The first task' }, { id: 2, content: 'The second task' }, { id: 3, content: 'The third task' }, { id: 4, content: 'The fourth task' }, { id: 5, content: 'The fifth task' }, ], }; export default function Home() { const [state, setState] = useState(initialData); return ( <DragDropContext> <div style={{ display: 'flex', flexDirection: 'column', background: '#0E1012', minHeight: '100vh', width: '100%', color: ""#E8E8EA", paddingBottom: '2rem', }} > <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', paddingTop: '4rem', paddingBottom: '4rem', }} > <h2 style={{ fontsize: '1.875rem' }}>react-beautiful-dnd</h2> <p style={{ fontSize: '20px', color: '#9B9B9B' }}></p> </div> <div style={{ display: 'flex', justifyContent: 'center', paddingInlineStart: '4rem', }} > <Column tasks={state.tasks} /> </div> </div> </DragDropContext> ); }
2. Column.js
import React from 'react'; import { Draggable, Droppable } from 'react-beautiful-dnd'; const Column = ({ tasks }) => { return ( <> <div style={{ display: 'flex', borderRadius: '3px', background: '#16181D', width: '500px', height: '610px', flexDirection: 'column', position: 'relative', }} > <Droppable droppableId='col'> {(droppableProvided) => { return ( <div style={{ display: 'flex', padding: '1.5rem', flexDirection: 'column', flex: '1', }} {...droppableProvided.droppableProps} ref={droppableProvided.innerRef} > {tasks.map((task, index) => { return ( <Draggable key={task.id} draggableId={task.id.toString()} index={index} > {(draggableProvided, draggableSnapshot) => { <div style={{ display: 'flex', marginBottom: '1rem', height: '100px', background: '#242731', borderRadius: '3px', padding: '1.5rem', alignItems: 'center', '&:active': { background: '#23252f', }, }} {...draggableProvided.dragHandleProps} {...draggableProvided.draggableProps} ref={draggableProvided.innerRef} > <p style={{ fontSize: '20px' }}>{task.content}</p> </div>; }} </Draggable> ); })} </div> ); }} </Droppable> </div> </> ); }; export default Column;
package.json配置
{ "name": "dnd", "version": "0.1.0", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { "next": "12.3.1", "react": "18.2.0", "react-beautiful-dnd": "^13.1.1", "react-dom": "18.2.0" }, "devDependencies": { "eslint": "8.24.0", "eslint-config-next": "12.3.1" } }
疑问:已按要求绑定ref到DOM元素,问题依旧,是否是类组件与函数组件声明方式导致的?
解决方案
核心问题是Column.js中Draggable的渲染回调函数没有返回元素——你只是写了JSX结构,但没有通过return将其返回,导致react-beautiful-dnd无法获取到绑定了innerRef的DOM节点,进而抛出错误。
修改Column.js中Draggable的渲染回调,添加return:
{(draggableProvided, draggableSnapshot) => { // 添加return返回JSX元素 return ( <div style={{ display: 'flex', marginBottom: '1rem', height: '100px', background: '#242731', borderRadius: '3px', padding: '1.5rem', alignItems: 'center', '&:active': { background: '#23252f', }, }} {...draggableProvided.dragHandleProps} {...draggableProvided.draggableProps} ref={draggableProvided.innerRef} > <p style={{ fontSize: '20px' }}>{task.content}</p> </div> ); }}
同时修正两个细节错误:
- Index.js中h2的style属性拼写错误:
fontsize改为fontSize - Index.js中color值的引号错误:
color: ""#E8E8EA"改为color: "#E8E8EA"
修改后重新运行项目,错误即可解决。
内容的提问来源于stack exchange,提问作者Rishabh Mehta
相关产品推荐
相关产品推荐

