简体   繁体   English

为什么 setState 会导致我的 React 应用程序 go 进入无限循环?

[英]Why does setState cause my React app go into infinite loop?

I am trying to render the following component, which is supposed to take the value of a few account level values and render the subtotal in a div.我正在尝试渲染以下组件,该组件应该采用一些帐户级别值的值并将小计呈现在 div 中。 This is the code这是代码

import * as React from 'react';
import { ILiquidiManagerProps } from './ILiquidiManagerProps';
import {AccountValue} from './AccountFields';
import {LiquidTEUR} from './DummyContent';

interface SubtotalState {
    Account?: any,
    SubtotalValue?: any
  }

export default class SubtotalValues extends React.Component<ILiquidiManagerProps, SubtotalState> {
    public constructor(props: ILiquidiManagerProps) {
        super(props);
        this.state = {
            Account: LiquidTEUR.Subcategories.find(item => item.Name == this.props.label),
            SubtotalValue: 0
        }
    }
    
    private getText = data => {
        this.setState({SubtotalValue: data});
    }

    private initiateValue = () => {
        let Account = this.state.Account;
        let subtotal = 0;
        Account.Accounts.map((item) => {
            subtotal += item.Value;
        })
        this.setState({SubtotalValue: subtotal});
    }

    public render(): React.ReactElement<ILiquidiManagerProps> {
        this.initiateValue();
        return(
            <React.Fragment>
            <a className="collapsible" href="#">
                <div 
                    className={`p-2 text-right value ` + this.props.bgColor + ` font-weight-bold ` + this.props.textColor}
                    data-date={this.props.date}
                    data-name={this.props.label}
                >{this.state.SubtotalValue}</div></a>
            <div className="content hidden">
                {this.state.Account.Accounts.map((item, key) => {
                    return <AccountValue key={key} label={item.Value} getValue={this.getText} subtotal={this.state.SubtotalValue} />;
                })}
                <span className="add-pos">&nbsp;</span>
            </div>
            </React.Fragment>
        );
    }
}

This is the error message it generates这是它生成的错误消息

Uncaught (in promise) Invariant Violation: Maximum update depth exceeded.未捕获(承诺)不变违规:超过最大更新深度。 This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React limits the number of nested updates to prevent infinite loops. React 限制了嵌套更新的数量以防止无限循环。

I have tried several different ways of setting the state of the subtotal, but I always seem to be getting the same error, and I am not sure where I am causing an infinite loop.我尝试了几种不同的方法来设置小计的 state,但我似乎总是遇到同样的错误,我不确定我在哪里导致了无限循环。

  1. You call this.initiateValue when the component renders.在组件呈现时调用this.initiateValue
  2. initiateValue sets the state initialValue 设置initiateValue
  3. Setting the state triggers a render设置 state 会触发渲染
  4. GOTO 1转到 1

You probably want to call initiateValue fromcomponentDidMount instead.可能想改为从componentDidMount调用initiateValue

(Or switch to writing a function component and putting it inside a useEffect hook). (或者切换到编写 function 组件并将其放入useEffect挂钩中)。

You shouldn't use setState() inside render method as you are using this.initiateValue();您不应该在使用 this.initiateValue(); 时在 render 方法中使用setState() this.initiateValue();

Because as you know whenever setState() is called re-rendering happens that's the reason it's going for infinite.因为正如您所知道的,每当调用setState()时,都会发生重新渲染,这就是它无限运行的原因。

If you want to initialize data call inside componentDidMount() or useEffect()如果要在componentDidMount()useEffect()中初始化数据调用

For more understanding, you can refer to Calling setState() in React from render method更多理解可以参考React中从render方法调用setState()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM