ReactJS 父表格行选择操作导致嵌套表格渲染崩溃问题
问题根因
1. useEffect依赖错误引发死循环
你在FirstTable、SecondTable的useEffect中调用setTableData更新状态,但依赖数组同时包含了tableData本身:每次setTableData触发组件重渲染,useEffect都会检测到tableData发生变化,再次执行接口请求并更新tableData,天然形成无限重渲染循环。
仅两层组件存在时,循环触发频率尚未触达React渲染深度阈值,所以不会崩溃;当三层组件同时进入循环时,渲染栈占用直接超限,触发页面崩溃。
2. 下级组件状态未联动重置
重新选择FirstTable的行时,你没有清空SecondTable的行选中状态,因此ThirdTable始终保持渲染状态,三层组件同步进入重渲染循环,直接放大了死循环的影响。
3. 条件渲染判断逻辑错误
你当前toggledcomponent的渲染判断条件是传入的filters,而非当前组件的行选中状态:只要filters为真值,下级表格就不会卸载,内部状态也不会主动重置,不符合你选中上级行后重置下级状态的需求。
解决方案
1. 修正useEffect依赖
将setTableData改为函数式更新写法,从依赖数组中移除tableData相关变量,从根源切断死循环:
// 原代码 useEffect(() => { APIcall(params).then((data) => { if (data !== undefined) { setTableData({ ...tableData, // 其余字段赋值 }); } }); }, [props.filters, tableData.page, column]); // 修改后代码 useEffect(() => { APIcall(params).then((data) => { if (data !== undefined) { setTableData(prevTableData => ({ ...prevTableData, // 其余字段赋值 })); } }); }, [props.filters, column]);
如果需要用到tableData.page作为请求参数,直接从prevTableData中取值即可,无需放入依赖数组。
2. 修正条件渲染逻辑+自动重置下级状态
新增当前组件的行选中状态作为下级表格的渲染判断条件,同时给下级表格绑定key为当前选中行的唯一标识:只要选中行发生变化,React会自动卸载旧的下级组件、渲染新的组件,下级所有内部状态(包括SecondTable的行选中状态、ThirdTable的渲染状态)会自动清空,完全符合你的预期需求。
// FirstTable组件内新增行选中状态 const [selectedRowId, setSelectedRowId] = useState(null); const onRowSelection = (e) => { // 先更新选中状态 setSelectedRowId(e.row.id); APIcall_2(params).then((results)=>{ setValues({...}); }); }; // 调整条件渲染逻辑 const toggledcomponent = () => { if (!selectedRowId) { return <div><p>请选择行</p></div>; } // key变更时自动重建SecondTable,清空所有内部状态 return <div><SecondTable key={selectedRowId} filters={filters}/></div>; };
SecondTable组件也按照相同逻辑修改即可。
内容的提问来源于stack exchange,提问作者Fegendet

