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

ReactFlow连接节点时获取节点数据遇空值问题求助

解决ReactFlow中onConnect无法获取连接节点数据的问题

问题根源分析

  • 类型断言错误:对Connection参数的类型处理有误,source和target本身是string | null | undefined类型,直接断言为string会导致类型不匹配,甚至在值为null时引发错误。
  • 节点查找方式错误:nodes是数组而非对象,不能用nodes[source]这种索引方式查找节点,必须用数组find方法匹配节点ID。
  • 依赖项缺失:onConnect的useCallback依赖数组中缺少nodes,导致回调无法获取最新节点列表。
  • 未处理空值情况:没有对source或target为null的情况做容错处理,直接查找会引发异常。

修复步骤

  1. 修正类型处理:正确解构Connection参数,先判断source和target是否有效。
  2. 改用数组查找节点:使用nodes.find(node => node.id === id)从节点数组中匹配对应节点。
  3. 补充依赖项:将nodes添加到useCallback的依赖数组,确保回调能获取最新节点数据。
  4. 增加空值校验:在获取节点前校验source和target的有效性,避免空值引发错误。

修改后的完整代码

function Flow() {
  const [elements, setElements] = useState(initialNodes);
  const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
  const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
  const [isSidebarOpen, setIsSidebarOpen] = useState(true);

  const onConnect = useCallback(
    (params: Connection) => {
      // 解构并校验source和target的有效性
      const { source, target } = params;
      if (!source || !target) {
        console.warn("无效的连接:source或target为空");
        return;
      }

      // 从nodes数组中查找对应节点
      const sourceNodeData = nodes.find(node => node.id === source);
      const targetNodeData = nodes.find(node => node.id === target);

      // 输出节点数据
      if (sourceNodeData && targetNodeData) {
        console.log('Source Node Data:', sourceNodeData);
        console.log('Target Node Data:', targetNodeData);
      } else {
        console.warn("未找到对应的源节点或目标节点");
      }

      // 添加新边并更新状态
      const updatedEdges = addEdge(params, edges);
      setEdges(updatedEdges);
    },
    [edges, setEdges, nodes] // 补充nodes到依赖数组
  );

  const toggleSidebar = () => {
    setIsSidebarOpen(!isSidebarOpen);
  };

  const addNode = (nodeType: string) => {
    const newNode = {
      id: `dndnode_${nodes.length}`,
      type: nodeType,
      data: { label: `Node ${nodes.length + 1}` },
      position: { x: Math.random() * 400, y: Math.random() * 400 },
    };
    setNodes((nds) => [...nds, newNode]);
  };

  const exportToYAML = () => {
    const transformedNodes = nodes.map((node) => {
      const { id, data } = node;
      return { id, ...data };
    });

    const yamlContent = yaml.dump({ nodes: transformedNodes, edges });
    downloadYAML(yamlContent, "flow.yaml");
  };

  const updateNodeData = (nodeId: string, newData: any) => {
    setNodes((prevNodes) =>
      prevNodes.map((node) =>
        node.id === nodeId
          ? { ...node, data: { ...node.data, ...newData } }
          : node
      )
    );
  };

  const nodeTypes = useMemo(
    () => ({
      custom: CustomNode,
      initialDagNode: InitialDagNode,
      sftp: SftpToGcs,
      convert: (nodeProps: NodeProps) => (
        <ConvertDataFile
          {...nodeProps}
          updateNodeData={(newData) => updateNodeData(nodeProps.id, newData)}
        />
      ),
      // ... 其他节点类型 ...
    }),
    [updateNodeData] // 补充正确的依赖
  );

  return (
    <>
      <NodeSearch onAdd={addNode} />
      <div className="parent-container">
        <Sidebar
          onAddNode={addNode}
          isSidebarOpen={isSidebarOpen}
          toggleSidebar={toggleSidebar}
        />
        <div className={styles.flow}>
          <ReactFlow
            nodes={nodes}
            onNodesChange={onNodesChange}
            edges={edges}
            onEdgesChange={onEdgesChange}
            onConnect={onConnect}
            nodeTypes={nodeTypes}
            defaultEdgeOptions={defaultEdgeOptions}
            connectionLineType={ConnectionLineType.SmoothStep}
            fitView
          >
            <MiniMap />
            <Controls />
          </ReactFlow>
        </div>
        <button className={styles.yamlbutton} onClick={exportToYAML}>
          Export to YAML
        </button>
      </div>
    </>
  );
}

额外说明

  • 如果连接是从节点的**handle(端口)**发起的,Connection参数中会有sourceHandle和targetHandle字段,若需要端口相关数据,可结合节点的data或handle配置进一步处理。
  • 确保initialNodes中的每个节点都有唯一且非空的id字段,这是查找节点的关键依据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:08:14