React beautiful dnd集成报错:Invalid hook call问题求助
解决React Beautiful Dnd的"Invalid hook call"错误
你遇到的这个错误是react-beautiful-dnd的典型兼容性问题,即使极简代码也触发,核心原因是React版本不兼容或项目存在多个React实例,以下是具体解决方法:
核心原因
react-beautiful-dnd目前仅支持React 17及更低版本,若你使用React 18+,其内部钩子调用逻辑无法适配React 18的新根渲染API(createRoot)和严格模式,直接导致钩子调用报错。另外如果项目中存在多个React实例(不同依赖引入了不同版本的React),也会触发该错误。
解决方案
1. 降级React到17版本
这是解决react-beautiful-dnd兼容性问题的最直接方案:
- 卸载当前React和ReactDOM:
npm uninstall react react-dom - 安装React 17版本:
npm install react@17 react-dom@17 - 修改项目入口文件的渲染代码,React 17不支持
createRoot,改用旧渲染方式:
此时你的极简代码即可正常运行。import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') );
2. 排查并移除重复的React实例
若不想降级React,可检查项目是否存在多个React版本:
- 运行命令查看依赖树:
若输出中出现多个React版本,说明第三方依赖重复引入了React。npm ls react - 在
package.json中添加resolutions字段(npm需配合npm-force-resolutions工具,yarn直接支持),强制所有依赖使用同一版本的React:"resolutions": { "react": "^17.0.2", "react-dom": "^17.0.2" } - 重新安装依赖:
npm install
3. 替换为兼容React 18的拖拽库
若需保留React 18,推荐使用维护更活跃、支持React 18的@dnd-kit库,示例代码如下:
import React, { useState } from 'react'; import ReactDOM from 'react-dom/client'; import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable'; const App = () => { const sensors = useSensors( useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates, }) ); const [items, setItems] = useState([1, 2, 3]); const handleDragEnd = (event) => { const { active, over } = event; if (active.id !== over.id) { setItems(prevItems => { const oldIndex = prevItems.indexOf(active.id); const newIndex = prevItems.indexOf(over.id); return arrayMove(prevItems, oldIndex, newIndex); }); } }; return ( <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd} > <SortableContext items={items} strategy={verticalListSortingStrategy} > <ul style={{ listStyle: 'none', padding: 0 }}> {items.map(item => ( <li key={item} style={{ padding: '8px', border: '1px solid #eee', margin: '4px 0' }}> {item} </li> ))} </ul> </SortableContext> </DndContext> ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
内容的提问来源于stack exchange,提问作者Daniil456
相关产品推荐
相关产品推荐

