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

React 网络图表当前节点无API数据时加载前一节点内容的实现问题

解决方案

核心逻辑是新增节点访问历史栈记录跳转路径,空数据返回时从历史栈回溯到上一个有效节点,同时补充原有代码缺失的实例销毁逻辑避免内存泄漏,修改后代码如下:

const NetworkGraph = (props: any) => {
  const container = useRef<HTMLInputElement | null>(null);
  const networkRef = useRef<Network | null>(null); // 存储network实例用于销毁
  const [nodeId, setNodeId] = useState(props.nodeId);
  // 新增历史栈,初始存储根节点ID
  const [nodeHistory, setNodeHistory] = useState<number[] | string[]>([props.nodeId]);
  const { graphData, isLoading } = useGetNetowrkGraphData(nodeId); // 自定义hook发起API请求
  
  useEffect(() => {
    if (isLoading === false) {
      if (graphData.nodes.length <= 0) {
        setMessage('No data found', 'error');
        // 回退逻辑:历史栈长度大于1时才回退,避免误删初始根节点
        if (nodeHistory.length > 1) {
          // 移除最后一个无效节点ID
          const newHistory = nodeHistory.slice(0, -1);
          setNodeHistory(newHistory);
          // 回退到上一个有效节点
          setNodeId(newHistory[newHistory.length - 1]);
          // 直接返回,无需渲染当前无效数据对应的图表
          return;
        }
      }

      const nodes = new DataSet(graphData.nodes);
      const edges = new DataSet(graphData.edges as any[]);
      const networkData = { nodes: nodes, edges: edges };

      // 销毁之前的实例避免重复渲染和内存泄漏
      if (networkRef.current) {
        networkRef.current.destroy();
      }
      // 新实例存入ref
      networkRef.current = container.current && new Network(container.current, networkData, options);

      networkRef.current?.on('doubleClick', function (params) {
        var ids = params.nodes;
        var clickedNodes = nodes.get(ids);

        if (clickedNodes && clickedNodes.length > 0) {
          const newNodeId = clickedNodes[0].id;
          setNodeId(newNodeId);
          // 新节点加入历史栈
          setNodeHistory(prev => [...prev, newNodeId]);
        }
      });
    }

    // 组件卸载时销毁实例
    return () => {
      if (networkRef.current) {
        networkRef.current.destroy();
      }
    }
  }, [
    container,
    nodeId,
    graphData.nodes,
    graphData.edges,
    isLoading,
    setNodeId,
    setMessage,
    nodeHistory,
  ]);

  if (isLoading) return <div>Loading...</div>;

  return (
    <>
      <Div>
          <div ref={container}/>
      </Div>
    </>
  );
};

export default NetworkGraph;

如果需要支持浏览器返回键回退节点,可以进一步将历史栈和浏览器history API绑定,无需修改现有核心逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:54:04