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

React传递props给图表组件触发Too many re-renders无限循环问题求助

问题原因

你遇到的无限循环问题根因是App.js中直接在组件函数顶层调用了setData:
React组件每次渲染都会完整执行函数体内的所有代码,你每次执行App函数都会调用setData更新状态,状态更新又会触发组件重新渲染,重新渲染又会再次调用setData,由此形成无限循环。
将数据放在Graph.js的useState中不会出现问题,是因为你仅将数据作为useState的初始值传入,没有在顶层直接调用状态更新函数,不会触发重复渲染。

修复方案

1. 修正App组件的状态初始化逻辑

二选一即可:

方案A:直接将初始值传入useState(最适合当前静态初始数据的场景)

import { useState } from 'react';
import Graph from './Graph';

function App() {
  // 直接把初始数据作为useState的默认值,不要在顶层调用setData
  const [data, setData] = useState({
    nodes:[
        {name:"Max"},
        {name:"George"},
        {name:"Jesus"},
        {name:"Ben"},
        {name:"James"},
        {name:"Sam"},
        {name:"Sassms"}
    ],
    edges:[
        {source:"Max", target:"George"},
        {source:"George", target:"Jesus"},
        {source:"Jesus", target:"Max"},
        {source:"Jesus", target:"Ben"},
        {source:"James", target:"Ben"},
        {source:"Sam", target:"Sassms"},
        {source:"Sam", target:"Ben"}
    ]
  })

  return (
    <Graph colour="Grey" data={data} setData={setData}/>
  );
}

方案B:如果是异步获取数据,将setData放在useEffect中执行

import { useState, useEffect } from 'react';
import Graph from './Graph';

function App() {
  const [data, setData] = useState(null)

  // 空依赖数组保证这段逻辑仅在组件首次挂载后执行1次
  useEffect(() => {
    // 模拟异步请求数据后更新状态
    setData({
      nodes:[
          {name:"Max"},
          {name:"George"},
          {name:"Jesus"},
          {name:"Ben"},
          {name:"James"},
          {name:"Sam"},
          {name:"Sassms"}
      ],
      edges:[
          {source:"Max", target:"George"},
          {source:"George", target:"Jesus"},
          {source:"Jesus", target:"Max"},
          {source:"Jesus", target:"Ben"},
          {source:"James", target:"Ben"},
          {source:"Sam", target:"Sassms"},
          {source:"Sam", target:"Ben"}
      ]
    })
  }, [])

  // 兜底渲染,避免Graph组件接收到null时报错
  if (!data) return <div>图表加载中</div>;
  return (
    <Graph colour="Grey" data={data} setData={setData}/>
  );
}

2. 后续修改数据自动刷新的注意事项

你当前Graph.js的逻辑已经可以满足数据变更自动重绘的需求,只需要在App.js中调用setData时,传入全新的状态对象,不要直接修改原状态的属性:

// 正确示例:新增节点,传入全新对象,触发自动重绘
const addNewNode = () => {
  setData(prevData => {
    return {
      ...prevData,
      nodes: [...prevData.nodes, {name: "New Node"}]
    }
  })
}

// 错误示例:直接修改原对象,React无法检测到状态变更,不会触发重绘
const badAddNode = () => {
  data.nodes.push({name: "New Node"})
  setData(data)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 08:15:04