You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中DND Kit状态更新失败及deleteProyect函数删除失效求助

React项目问题排查与修复

问题1:DnD Kit拖拽后状态无法正确更新

原因分析

  1. SortableContext的items属性错误传入完整项目对象数组,DnD Kit要求此处传入项目id的数组,用于标识可排序项。
  2. 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删除功能异常(点击无响应/需快速点击)

原因分析

  1. createProyect中使用prevProyects.length作为新项目id,删除项目后数组长度变化,会导致新增项目id与现有项目重复,删除时filter无法正确匹配目标id。
  2. ProyectContext初始化状态时直接赋值data引用,若data是外部可变数组,可能导致状态更新时出现引用混乱。
  3. 之前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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 04:18:09