Бесконечный цикл с React comonentDidUpdate - PullRequest
0 голосов
/ 19 сентября 2018

У меня есть родительский компонент App, который отображает маршрут с компонентом Report.Компонент App выполняет вызов ajax в своем методе componentDidMount, а отчет также выполняет некоторые вызовы ajax в своем методе componentDidUpdate, после чего он вызывает родительский метод 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}
                />
              )}
            />

Admin

...
  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));

1 Ответ

0 голосов
/ 19 сентября 2018

ComponentDidUpdate () будет вызываться всякий раз, когда реквизиты для дочернего компонента обновляются.

В этом сценарии происходит поток:

  1. reports={this.state.reports} передается дочернему элементуcomponent
  2. Затем дочерний элемент обновляется, поскольку он reports prop изменен
  3. Вызывается ComponentDidUpdate () и впоследствии запускает updateReports(newState) в родительском компоненте
  4. В родительском элементеКомпонент: состояние обновляется новыми отчетами
  5. Обновленный reports={this.state.reports} передается дочернему элементу
  6. . Повторите 2-5

Используя ComponentDidMount () в этомСценарий должен устранить проблему, но, что более важно, с точки зрения архитектуры решения, ваш сервисный вызов должен быть извлечен в отдельный файл и вызван из родительского элемента, что делает дочерний элемент немым компонентом.

Есть много вещей, которые я могу сказать, но яЯ просто здесь, чтобы уточнить, почему происходит петля: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...