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

如何修复React组件AnvendelsesDisplay的无限渲染循环问题

React组件无限循环问题排查与修复

问题现象

React视图触发无限循环,报错信息如下:

Too many re-renders. React limits the number of renders to prevent an infinite loop. renderWithHooks@http://localhost:3000/static/js/bundle.js:30378:19

问题出在AnvendelseDisplay组件,相关代码如下:

import { useState, useEffect } from "react"
import { Container } from 'react-bootstrap';
import BBRMapping from "./BBRMapping";

const AnvendelseDisplay = ({type, anvendelse}) => { 
    const [ a, setA ] = useState(0);
    
    const bbrmap = new BBRMapping();
    const val = bbrmap.MapBBRCode(type, anvendelse);
    setA(val);
    return (
        <>
        <p>Anvendelse: {a}</p>
        </>
    );
}

const ResultsDisplay = (props) => { 

    const hest = props.hest;
    const bbrmap = new BBRMapping();

    return(
        <>
            <Container>
                <h2>Grund</h2>
                <p>Grundareal: {hest.grund.grundareal.grundareal} kvm</p>
                <p>BFE-nummer: {hest.grund.grundareal.bfeNummer}</p>
           </Container>
            {hest.enheder.map((h, i) => {
                return(
                <Container>
                    <h2>Enhed</h2>
                    <p>Enhedensanvendelse: {h.enh020EnhedensAnvendelse}</p>
                    <p>Antal vaerelser: {h.enh031AntalVærelser}</p>
                    <p>Antal badevaerelser: {h.enh066AntalBadeværelser}</p>
                    <p>Antal vandskyllede toiletter: {h.enh065AntalVandskylledeToiletter}</p>
                    <p>Boligtype: {bbrmap.MapBoligtype(h.enh023Boligtype)}</p>
                    <p>Enhedens samlede areal: {h.enh026EnhedensSamledeAreal}</p>
                    <p>Areal til beboelse: {h.enh027ArealTilBeboelse}</p>
                    <p>Toiletforhold: {bbrmap.MapToiletforhold(h.enh032Toiletforhold)}</p>
                    <p>Badeforhold: {bbrmap.MapBadeforhold(h.enh033Badeforhold)}</p>
                    <p>Koekkenforhold: {bbrmap.MapKoekkenforhold(h.enh034Køkkenforhold)}</p>
                    <p>Energiforsyning: {bbrmap.MapEnergiforsyning(h.enh035Energiforsyning)}</p>
                </Container>
                )
            })}
            {hest.bygninger.map((h, i) => {
                return(
                <Container>
                    <h2>Bygning</h2>
                    <AnvendelseDisplay 
                        anvendelse={h.byg021BygningensAnvendelse} 
                        type="BygAnvendelse" />
                    <p>Tagdaekningsmateriale: {bbrmap.MapTagdaekningsmateriale(h.byg033Tagdækningsmateriale)}</p>
                    <p>Ydervaeggens materiale: {bbrmap.MapYdervaeggensMateriale(h.byg032YdervæggensMateriale)}</p>
                    <p>Samlede boligareal: {h.byg039BygningensSamledeBoligAreal}</p>
                    <p>Varmeinstallation: {bbrmap.MapVarmeinstallation(h.byg056Varmeinstallation)}</p>
                    <p>Opfoerelsesaar: {h.byg026Opførelsesår}</p>
                    <p>Antal etager: {h.byg054AntalEtager}</p>
                    <p>Koordinat: {h.byg404Koordinat} (Koordinatsystem: {h.byg406Koordinatsystem})</p>
                    <p>Bebygget areal: {h.byg041BebyggetAreal}</p>
                </Container>
                );
            })}
        </>
    );
}      

export default ResultsDisplay;

BBRMapping.MapBBRCode()的实现:

MapBBRCode(domain, key) 
{ 
    fetch(`/bbrkode/${domain}/${key}`)
            .then((response) => response.json())
            .then((data) => {
                    console.log(`MapBBRCode: ${data.value}`);
                    return data.value;
            })
}

问题原因

  1. 无限循环触发逻辑:AnvendelseDisplay组件在渲染阶段直接调用setA(val),每次组件渲染都会执行状态更新,状态更新又会触发组件重新渲染,形成闭环循环。
  2. 异步函数返回值无效:MapBBRCode内部使用异步fetch,但没有返回Promise,导致val实际为undefined,且无法正确获取异步请求结果。

修复方案

步骤1:修正MapBBRCode函数,返回Promise

让函数返回fetch的Promise链,以便组件能正确处理异步结果:

MapBBRCode(domain, key) 
{ 
    return fetch(`/bbrkode/${domain}/${key}`)
            .then((response) => response.json())
            .then((data) => {
                    console.log(`MapBBRCode: ${data.value}`);
                    return data.value;
            })
}

步骤2:用useEffect包裹状态更新逻辑

将异步请求和状态更新放到useEffect中,仅当依赖项变化时执行,避免重复渲染:

const AnvendelseDisplay = ({type, anvendelse}) => { 
    const [ a, setA ] = useState(0);
    
    useEffect(() => {
        const fetchAndUpdate = async () => {
            const bbrmap = new BBRMapping();
            const val = await bbrmap.MapBBRCode(type, anvendelse);
            setA(val);
        };
        fetchAndUpdate();
    }, [type, anvendelse]); // 仅当type或anvendelse变化时执行

    return (
        <>
        <p>Anvendelse: {a}</p>
        </>
    );
}

说明

  • useEffect的依赖数组确保只有当输入参数type或anvendelse改变时,才会重新发起请求并更新状态,彻底切断无限循环的触发条件。
  • 使用async/await处理异步请求,让逻辑更清晰,也能正确捕获fetch返回的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:25:06