在for循环中使用useState导致过多重渲染错误求助
解决React中"too many re-renders"错误的方案
问题根源
你当前的代码在渲染表格的getRows函数里循环调用checkValue,而checkValue内部调用了setEditRates和setEditNetRates这两个状态更新函数。每次调用状态更新都会触发组件重新渲染,重新渲染又会再次执行getRows和checkValue,形成无限循环,最终导致"too many re-renders"错误。
解决方案
把基于viewData更新状态的逻辑从渲染流程中抽离,放到useEffect钩子中,只在viewData发生变化时执行状态更新,避免每次渲染都触发状态变更。
修改后的完整代码
import { useState, useEffect } from 'react'; export default function SettingView() { const [editRates, setEditRates] = useState<boolean>(false); const [editNetRates, setEditNetRates] = useState<boolean>(false); // 用useEffect监听viewData变化,更新状态 useEffect(() => { if (!viewData) return; const targetItem = Object.values(viewData).find(item => item.field.name === 'specifc_name'); if (!targetItem) return; if (!targetItem.has_override && targetItem.value === 'none') { setEditRates(true); setEditNetRates(false); } else if (targetItem.has_override && targetItem.value !== 'none') { setEditRates(false); setEditNetRates(true); } }, [viewData]); // 依赖viewData,只有当它变化时才执行 function renderTableData() { return ( <> <table headings={[ {content: 'Name'}, {content: 'Inherited value'}, {content: 'Overwrite value'}, { content: 'Edit', align: 'center', } ]} rows={getRows(viewData)} /> </> ) } function getRows(viewOutput) { const rows: Array<Row> = []; if (viewOutput !== undefined) { const sortFunc = (a:string, b:string) => { const fa = a.toLowerCase(), fb = b.toLowerCase(); if (fa < fb) { return -1; } if (fa > fb) { return 1; } return 0; } const sortedRows = Object.values(viewOutput).sort((a, b) => sortFunc(a.field.name, b.field.name)); for (let item of sortedRows) { rows.push({ cells: [ { content: ( <SettingTitle title={item.field.name} description={item.field.description} isFiltered={item.field.name === filtered_item} /> ) }, { content: item.default_value ? item.default_value : "" }, { content: item.override_value ? item.override_value : "" }, { content: showEditButton(item) ? <Button text="Edit" variant="primary" destructive={false} type="button" size="medium" loading={false} wide={false} onClick={() => {}} /> : "" }, ] }); } } return rows; } function showEditButton(item: any) { if (item.is_editable) { if (item.field.name === 'name1') { return editRates; } else if (item.field.name === 'name2') { return editNetRates; } return true; } return false; } }
额外说明
- 补上原代码中
getRows缺失的return rows语句,否则表格无法获取行数据。 - 简化
showEditButton的条件判断逻辑,直接返回对应状态值,代码更简洁。 useEffect依赖数组加入viewData,确保仅在数据源变化时执行状态更新,避免不必要的重复执行。
内容的提问来源于stack exchange,提问作者udarts
相关产品推荐
相关产品推荐

