我有一个父App组件,该组件使用Report组件呈现路线。 App组件在其componentDidMount方法中进行了ajax调用,而Report也在其componentDidUpdate方法中进行了一些ajax调用,这时它调用了父级的updateReports方法。该应用程序陷入无限循环,在此循环中,孩子不断反复进行其ajax调用。
应用
...
updateReports(report) {
console.log('updateReports', report)
if (report.submittal) {
this.setState({ reports: { submittal: report.submittal } });
if (report.specification) {
this.setState({ reports: { specification: report.specification } });
}
}
}
...
componentDidMount() {
console.log('environment', process.env);
console.log('App state', this.state);
if (!this.state.projectName) {
const err = new Error('Project Name must be supplied in the url: /<projectName>');
return this.handleError(err);
}
this.populateProjectId();
}
populateProjectId() {
return Api.getProjectId(process.env.REACT_APP_API_PATH, this.state.projectName)
.then((projectId) => {
console.log('App adding projectId to state', projectId);
this.setState({ projectId });
})
.catch((err) => {
console.log(err);
this.handleError(err);
});
}
...
render() {
const commonProps = {
query: this.state.query,
projectName: this.state.projectName,
projectId: this.state.projectId
};
...
<Route
path="/:projectName/admin"
render={(props) => (
<Admin
{...{ ...commonProps }} reports={this.state.reports}
updateReports={this.updateReports}
handleError={this.handleError}
/>
)}
/>
管理员
...
componentDidUpdate(prevProps, prevState, snapshot) {
console.log('Admin componentDidUpdate')
const { projectId } = this.props;
const apiPath = process.env.REACT_APP_API_PATH;
Api.fetchReport(apiPath, projectId, 'submittal', null)
.then((res) => {
console.log('submittal report result', res);
return res;
})
.then((submittal) => {
Api.fetchReport(apiPath, projectId, 'specification', null).then((res) => {
console.log('specification report result', res);
const newState = { submittal, specification: res };
console.log('Calling updateReports', newState);
this.props.updateReports(newState);
});
})
.catch((err) => {
console.log(err);
this.handleError(err);
});
}
render() {
return (
<div>
<Report reports={this.props.reports} />
</div>
);
}
}
export default withRouter(withStyles(styles)(Admin));
答案 0 :(得分:3)
ComponentDidUpdate()。
在这种情况下,流程是:
reports={this.state.reports}
传递给子组件reports
道具已更改updateReports(newState)
reports={this.state.reports}
被传递给孩子在这种情况下使用ComponentDidMount()应该可以解决此问题,但更重要的是,从解决方案体系结构的角度来看,应该将服务调用提取到一个单独的文件中并从父级调用,从而使子级成为笨拙的组件。
我可以说很多,但我只是在这里说明为什么会发生循环:P