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

使用react-dnd库拖拽功能失效,提示'dropped不是函数'

react-dnd拖拽报错“dropped is not function”问题排查与修复

核心问题1:Context取值错误

在Droppable.js中,通过useContext获取的是Context的value对象,而非直接拿到dropped函数。当前写法直接调用对象导致类型错误:

// 错误写法:拿到的是{ dropped: 函数 }这个对象
const dropped = React.useContext(SelectedNFTContext);
drop: (item, monitor) => dropped(item.id),

正确做法是解构出函数:

const { dropped } = React.useContext(SelectedNFTContext);

核心问题2:Drag组件未传递拖拽数据

在NFTCards.js的useDrag配置中,缺少item属性定义,导致拖拽时Drop区域无法获取NFT的id参数。需要补充传递拖拽数据:

const [{ isDragging }, dragRef] = useDrag({
  type: "image",
  item: { id }, // 新增:传递当前NFT的id
  collect: (monitor) => ({
    isDragging: !!monitor.isDragging(),
  }),
});

额外问题:状态更新违反Immutable原则

在Sidebar.js的dropped函数中,直接修改了state数组中的原对象属性,React无法感知状态变化,同时可能引发不可预期的bug:

// 错误写法:直接修改原state对象
selectedNFT[0].status = "selected";

应创建新对象来更新状态:

const dropped = (id) => {
  setNftList(prev => {
    const selectedNFT = prev.find(nft => nft.id === id);
    if (!selectedNFT) return prev;
    // 创建新对象,避免修改原state
    const updatedNFT = { ...selectedNFT, status: "selected" };
    return prev.filter(nft => nft.id !== id).concat(updatedNFT);
  });
};

修正后的关键代码片段

Droppable.js 修正后

function Dropabble() {
  const { dropped } = React.useContext(SelectedNFTContext);
  const [{ isOver }, dropRef] = useDrop({
    accept: "image",
    drop: (item) => dropped(item.id),
    collect: (monitor) => ({
      isOver: !!monitor.isOver(),
    }),
  });
  // 其余代码保持不变
}

NFTCards.js 修正后

function NFTCards({ index, id, imgURL, title }) {
  const [{ isDragging }, dragRef] = useDrag({
    type: "image",
    item: { id },
    collect: (monitor) => ({
      isDragging: !!monitor.isDragging(),
    }),
  });
  // 其余代码保持不变
}

内容的提问来源于stack exchange,提问作者user16875752

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:25:41