使用react-dnd实现拖拽时useState嵌套状态被覆盖如何解决
问题原因
核心是React闭包陷阱:你传给useDrop的回调函数在组件初始化时就被创建,捕获了当时的lessonContent初始值(也就是content为空数组的状态)。后续组件重新渲染时,useDrop的回调没有更新依赖,一直引用最开始的旧状态,所以每次新增元素都是往空数组里加,自然会覆盖之前的内容。
修复方案
优先推荐使用状态更新的函数式写法,该方案不需要额外维护依赖,不受闭包影响:
const handleAddLessonElement = (element: Record<string, unknown>) => { // 从回调参数prev中直接拿到最新的state值 setLessonContent(prev => ({ ...prev, content: [...prev.content, element], })); };
如果要保留原有写法,也可以给useDrop补充依赖项,让回调随状态更新刷新:
const [{ isOver }, drop] = useDrop(() => ({ accept: 'card', drop: (item) => handleAddLessonElement(item), collect: (monitor) => ({ isOver: !!monitor.isOver(), }), // 新增依赖项,保证回调引用的永远是最新的lessonContent }), [lessonContent]);
内容的提问来源于stack exchange,提问作者Jesse Winton
相关产品推荐
相关产品推荐

