如何在componentDidUpdate()中更新组件的状态而不会陷入无限的重新渲染中?

时间:2019-12-10 23:46:43

标签: javascript reactjs

我有一个带有componentDidMount()方法的组件,该方法调用名为getData()的方法,该方法获取初始数据并设置该组件的初始状态。

class LogsSettings extends React.Component {
constructor(props) {
    super(props);

    this.settingsUrls = [
        "/ui/settings/logging"
    ];

    this.state = {
        configSettings: {},
        formSchema: formSchema
    };

    this.configSettings = {};
    this.selected = "general";

}

    getData = (url, selectedSetting) => {
    fetch(url)
        .then((response) => {
                if (response.status !== 200) {
                    console.log('Looks like there was a problem. Status Code: ' +
                        response.status);
                    return;
                }
                response.json().then((response) => {
                    //pass formschema here
                    console.log(selectedSetting);
                    let newFormSchema = this.setNonDefaultValues(response.data, formSchema.subsections);
                    Object.assign(this.configSettings, response.data);
                    this.setState({
                       configSettings : this.configSettings,
                        formSchema: newFormSchema
                   });
                });
            }
        )
        .catch((err) => {
            console.log('Fetch Error :-S', err);
        });
};


componentDidMount() {
    this.settingsUrls.map((settingUrl) => {
        this.getData(settingUrl, this.selected)

})

}

componentDidUpdate() {
    this.settingsUrls.map((settingUrl) => {
        this.getData(settingUrl, this.props.selectedSetting)

})

}



render() {

    return (
        <div className="card-wrapper">
            <h2>{formSchema.label.toUpperCase()}</h2>
            {
                formSchema.subsections.map((subSection) => {
                    return (
                        <>
                            <h3>{subSection['description']}</h3>
                            <div style={{marginBottom: '10px'}}></div>

                            {
                                subSection['input_fields'].map((inputField) => {
                                    return buildForm(inputField, this.handleChange)
                                })
                            }
                            <hr></hr>
                        </>
                    )
                })
            }
            <button className="button button-primary">Save Changes</button>
        </div>
    )
}

}

此组件中传递给selectedSetting方法的getData()参数将更改,但是当更改时,我需要更改组件的状态并获取特定于更改后的{ {1}}参数。

新的selectedSetting作为prop传递到组件中。问题在于,当组件陷入无限循环时,我无法将新的selectedSetting参数传递给我的selectedSetting方法来更新组件的状态。

如何将新的getData传递给selectedSetting方法而又不会陷入无限循环?这有可能吗?如果没有,我应该采取的最佳方法是什么?

请注意,getData()函数中尚未使用selectedSetting参数,但会使用该参数,它将用于从API调用和新的表单模式中获取数据,然后将其引至getData()ConfigSettings的状态已更改

1 个答案:

答案 0 :(得分:1)

如果您仔细查看组件的生命周期,则在挂载之后,将获取并更新组件。这将触发componentDidUpdate生命周期方法,该方法将执行相同的操作,从而导致无限循环。您需要有一个标志来检查this.props.selected是否已更改。如果没有,请不要获取数据,否则请正常获取。在更新方法中,您可以访问以前的道具。 (您也可以在componentShouldUpdate方法中执行此操作,但这完全有风险)

componentDidUpdate(prevProps) {
    if( prevProps.selectedSetting !== this.props.selectedSetting ){
       this.settingsUrls.map((settingUrl) => {
         this.getData(settingUrl, this.props.selectedSetting)
      })
    }
}

也只是一个提示,我注意到您的didMount方法使用默认的“常规”作为所选设置,因为如果要使用this.props.selectedSetting,则最好使用{{1}}并将默认道具设置为“常规”。