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

React Flow+TypeScript点击按钮创建可拖拽可连接节点问题求助

React Flow节点无法拖拽与连接问题解决方法

问题概述

使用TypeScript开发React Flow项目,依赖reactflow和react-flow-renderer包,点击按钮可新增节点,但存在两个核心问题:

  • 节点无法拖拽
  • 节点之间无法创建连接

问题根源

  1. 依赖包混用与版本问题:react-flow-renderer是React Flow的旧版包,当前官方已统一使用reactflow包,混用会导致功能异常。
  2. 状态管理错误:将节点(nodes)和边(edges)放在同一个数组中管理,不符合React Flow的状态管理规范。
  3. 缺少核心交互回调:未实现onNodesChange、onEdgesChange、onConnect这三个处理拖拽、连接的必要回调。
  4. 节点ID格式问题:使用Math.random()生成的数字ID可能导致识别异常,React Flow推荐使用字符串类型ID。

修复后的完整代码

/* -------------------------------------------------------------------------- */
/*                                  Libraries                                 */
/* -------------------------------------------------------------------------- */
import React, { useCallback, useState, useRef } from "react";
import ReactFlow, {
  Background,
  Controls,
  type Node,
  type Edge,
  type OnNodesChange,
  type OnEdgesChange,
  type Connection,
} from "reactflow";
// 必须导入React Flow样式
import "reactflow/dist/style.css";

/* -------------------------------------------------------------------------- */
/*                               Implementation                               */
/* -------------------------------------------------------------------------- */
const initialNodes: Node[] = [
  {
    id: "1",
    type: "input",
    data: { label: "Input Node" },
    position: { x: 100, y: 0 },
  },
];

const initialEdges: Edge[] = [];

/* -------------------------------------------------------------------------- */
/*                                  Function                                  */
/* -------------------------------------------------------------------------- */
export default function Flow() {
  const [nodes, setNodes] = useState<Node[]>(initialNodes);
  const [edges, setEdges] = useState<Edge[]>(initialEdges);
  const yPos = useRef(0);

  const addNode = useCallback(() => {
    yPos.current += 80;
    setNodes((prevNodes) => [
      ...prevNodes,
      {
        // 用时间戳生成唯一字符串ID
        id: `${Date.now()}`,
        position: { x: 100, y: yPos.current },
        data: { label: "new node" },
        style: {
          backgroundColor: "#00fff0",
        },
      },
    ]);
  }, []);

  // 处理节点变更(拖拽、缩放等)
  const onNodesChange: OnNodesChange = useCallback(
    (changes) => setNodes((prev) => ReactFlow.updateNodes(prev, changes)),
    []
  );

  // 处理边变更(删除、移动等)
  const onEdgesChange: OnEdgesChange = useCallback(
    (changes) => setEdges((prev) => ReactFlow.updateEdges(prev, changes)),
    []
  );

  // 处理节点连接
  const onConnect = useCallback(
    (connection: Connection) => {
      setEdges((prevEdges) => [
        ...prevEdges,
        {
          ...connection,
          id: `${connection.source}-${connection.target}`,
        },
      ]);
    },
    []
  );

  return (
    <div style={{ height: "100vh", width: "100%" }}>
      {/* React Flow容器需设置足够尺寸 */}
      <ReactFlow
        nodes={nodes}
        edges={edges}
        onNodesChange={onNodesChange}
        onEdgesChange={onEdgesChange}
        onConnect={onConnect}
        nodesDraggable={true}
        nodesConnectable={true}
      >
        {/* 可选:添加背景网格和控制面板 */}
        <Background />
        <Controls />
      </ReactFlow>

      <button onClick={addNode} className="p-2 m-2 rounded-md bg-[#00fff0]">
        Add
      </button>
    </div>
  );
}

关键改动说明

  • 依赖修正:移除react-flow-renderer,导入reactflow包的正确组件和样式文件,这是功能正常运行的基础。
  • 状态拆分:分别维护nodes和edges状态,符合React Flow的设计规范。
  • 添加交互回调:onNodesChange处理节点拖拽后的位置更新,onEdgesChange处理边的变更,onConnect处理新边的创建。
  • ID规范:改用时间戳生成唯一字符串ID,避免识别问题。
  • 容器样式:为React Flow容器设置足够的尺寸(如height: 100vh),确保交互区域正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:20:26