React中cloneMode状态变化时DraggableElement组件group prop不更新怎么办
问题根因
react-sortablejs 封装的 ReactSortable 组件依赖底层的 SortableJS 实例,这类实例仅在组件挂载时读取一次配置属性,默认不会响应式同步上层prop的变更,所以即使你传入的 group 值随 cloneMode 变化,底层实例也不会自动更新配置,导致功能不生效。
解决方案
- 方案1:强制重建组件(最稳妥,适配所有版本)
给父组件调用的每个DraggableElement增加绑定了cloneMode的key,当cloneMode变化时,会触发整个组件卸载后重新挂载,内部的ReactSortable会用最新的group配置初始化,父组件修改代码如下:
const Tasks = () => { const [cloneMode, setCloneMode] = useState(false); return ( <div className="tasks"> <DraggableElement key={`todo-${cloneMode}`} list={todo} setList={setTodo} cloneMode={cloneMode} /> <DraggableElement key={`inProgress-${cloneMode}`} list={inProgress} setList={setInProgress} cloneMode={cloneMode} /> <DraggableElement key={`done-${cloneMode}`} list={done} setList={setDone} cloneMode={cloneMode} /> </div> ); };
修改后可以删除 DraggableElement 内部 ReactSortable 上的 key={cloneMode} 属性,避免重复逻辑。
- 方案2:手动更新实例配置(避免重渲闪烁)
如果不需要卸载组件、希望保留现有状态避免动画闪烁,可以通过ref获取底层Sortable实例,监听cloneMode变化后手动更新group配置,DraggableElement修改代码如下:
import { useRef, useEffect } from 'react'; const DraggableElement = ({ list, setList, cloneMode }) => { const sortableRef = useRef(null); useEffect(() => { if (sortableRef.current?.sortable) { // 手动更新底层Sortable实例的group配置 sortableRef.current.sortable.option("group", cloneMode ? { name: "tasks_group", pull: "clone" } : "tasks_group"); } }, [cloneMode]); return ( <ReactSortable ref={sortableRef} group={ cloneMode ? { name: "tasks_group", pull: "clone" } : "tasks_group" } list={list} setList={setList} animation={200} delay={1} className="task-child_drag" > {list.map((e) => { return <TaskItem key={e._id} task={e} />; })} </ReactSortable> ); };
内容的提问来源于stack exchange,提问作者Ajit Kumar
相关产品推荐
相关产品推荐

