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

React DnD useDrag的canDrag属性不生效,拖拽条件控制异常求助

React DnD useDrag canDrag 属性不生效问题修复

问题场景

我需要在 props 中的 flag 变量大于等于 3 时,让组件支持拖拽。使用 React DnD 的 useDrag 钩子并配置了 canDrag 属性,但该属性未生效:

  • 代码中计算的 isDrag 变量输出值正确,完全符合 flag >= 3 的判断逻辑
  • 若将 canDrag 设为 !isDrag,仅当 flag 为默认值 0 时拖拽生效,其他情况均失效

原代码:

const [{ isDragging }, drag] = useDrag(() => {
  const isDrag = flag >= 3;
  console.log(isDrag); // 此处输出值正确
  return {
    type: ItemTypes.GAME,
    item: { id: `${row}_${col}`, row: row, col: col },
    options: {
      dropEffect: "copy",
    },
    collect: (monitor: DragSourceMonitor) => ({
      isDragging: monitor.isDragging(),
    }),
    canDrag: isDrag,
  };
}, [flag, row, col]);

// 后续渲染代码...
const highlight =
  row == minDelta.row && col == minDelta.col
    ? `3px solid red`
    : `3px solid #e6e6e6`;
const tileColor = `rgb(${color.join(", ")})`;
return (
  <Grid item xs>
    <StyledGridCell
      ref={drag}
      tilecolor={tileColor}
      highlight={highlight}
      title={tileColor}
    />
  </Grid>
);

解决方案

问题出在 canDrag 的赋值方式上。直接传递布尔值时,React DnD 可能无法在 flag 变化时实时更新拖拽权限判断。正确的做法是将 canDrag 定义为函数,让它每次判断拖拽状态时都能获取最新的 flag 值:

修正后的代码(简洁版)

const [{ isDragging }, drag] = useDrag(() => ({
  type: ItemTypes.GAME,
  item: { id: `${row}_${col}`, row: row, col: col },
  options: {
    dropEffect: "copy",
  },
  collect: (monitor: DragSourceMonitor) => ({
    isDragging: monitor.isDragging(),
  }),
  // 改为函数形式,实时判断最新的flag值
  canDrag: () => flag >= 3,
}), [flag, row, col]);

// 后续渲染代码不变...

保留日志输出的版本

如果需要保留 isDrag 的日志打印,也可以这样写:

const [{ isDragging }, drag] = useDrag(() => {
  const isDrag = flag >= 3;
  console.log(isDrag);
  return {
    type: ItemTypes.GAME,
    item: { id: `${row}_${col}`, row: row, col: col },
    options: {
      dropEffect: "copy",
    },
    collect: (monitor: DragSourceMonitor) => ({
      isDragging: monitor.isDragging(),
    }),
    // 用函数返回当前计算的isDrag值
    canDrag: () => isDrag,
  };
}, [flag, row, col]);

// 后续渲染代码不变...

原因说明

  • 当 canDrag 是函数时,React DnD 会在每次尝试拖拽时调用该函数,确保获取最新的状态值
  • 直接传递布尔值时,只有在 useDrag 的工厂函数重新执行(依赖变化)时才会更新,但可能存在状态同步延迟,导致判断逻辑不生效

内容的提问来源于stack exchange,提问作者Ammar Hayder Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:15:29