React中DND Kit状态更新失败及deleteProyect函数删除失效求助
React项目问题排查与修复
问题1:DnD Kit拖拽后状态无法正确更新
原因分析
SortableContext的items属性错误传入完整项目对象数组,DnD Kit要求此处传入项目id的数组,用于标识可排序项。ProyectCard的key使用proyect.title,若存在标题重复的项目,会导致React渲染时无法正确识别组件,状态更新后视图不刷新。
修复代码
修改ProyectList.jsx:
import React, { useContext } from "react"; import { ProyectContext } from "../../context/ProyectContext"; import { DndContext, closestCenter } from "@dnd-kit/core"; import { arrayMove, SortableContext, verticalListSortingStrategy, } from "@dnd-kit/sortable"; import ProyectCard from "./ProyectCard"; function ProyectList() { const { proyects, setProyects } = useContext(ProyectContext); function handleDragEnd(evt) { const { active, over } = evt; // 避免拖拽同一元素时触发无意义更新 if (active.id === over.id) return; setProyects((prevProyects) => { const oldIndex = prevProyects.findIndex( (proyect) => proyect.id === active.id ); const newIndex = prevProyects.findIndex((proyect) => proyect.id === over.id); return arrayMove(prevProyects, oldIndex, newIndex); }); } return ( <> <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}> <SortableContext strategy={verticalListSortingStrategy} // 传入id数组而非对象数组 items={proyects.map(proyect => proyect.id)} > {/* 改用id作为key,确保唯一性 */} {proyects.map((proyect) => ( <ProyectCard key={proyect.id} proyect={proyect} /> ))} </SortableContext> </DndContext> </> ); } export default ProyectList;
问题2:deleteProyect删除功能异常(点击无响应/需快速点击)
原因分析
createProyect中使用prevProyects.length作为新项目id,删除项目后数组长度变化,会导致新增项目id与现有项目重复,删除时filter无法正确匹配目标id。ProyectContext初始化状态时直接赋值data引用,若data是外部可变数组,可能导致状态更新时出现引用混乱。- 之前
ProyectCard的key不唯一,也会导致删除后视图不更新,让用户误以为删除功能失效。
修复代码
修改ProyectContext.jsx:
import React, { useState, createContext, useEffect } from "react"; import { proyects as data } from "../data/proyects"; export const ProyectContext = createContext({}); export function ProyectContextProvider(props) { const [proyects, setProyects] = useState([]); useEffect(() => { // 创建新数组,避免直接引用外部data setProyects([...data]); }, []); function createProyect(title, platform) { setProyects((prevProyects) => { // 生成唯一id,避免重复(用最大id+1) const maxId = prevProyects.length > 0 ? Math.max(...prevProyects.map(p => p.id)) : 0; return [ ...prevProyects, { id: maxId + 1, title: title, platform: platform, img: "https://www.lacorformacion.com/wp-content/uploads/curso-por-defecto.jpg", }, ]; }); } function deleteProyect(proyectID) { setProyects((prevProyects) => prevProyects.filter((proyect) => proyect.id !== proyectID) ); } return ( <ProyectContext.Provider value={{ proyects, setProyects, createProyect, deleteProyect }} > {props.children} </ProyectContext.Provider> ); }
额外说明
- 确保
proyects数组中的每个项目id始终唯一,这是DnD Kit排序和删除功能正常工作的核心前提。 - 若项目数量较多,推荐使用UUID生成唯一id,避免基于数组长度或最大id的潜在冲突。
内容的提问来源于stack exchange,提问作者user25357387
相关产品推荐
相关产品推荐

