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

在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;
    }
}

额外说明

  1. 补上原代码中getRows缺失的return rows语句,否则表格无法获取行数据。
  2. 简化showEditButton的条件判断逻辑,直接返回对应状态值,代码更简洁。
  3. useEffect依赖数组加入viewData,确保仅在数据源变化时执行状态更新,避免不必要的重复执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:09:55