Ошибка Maximum update depth exceeded?

Получаю данный с помощью fetch при componentDidMount после обновляю state, на обновление state стоит обновление счетчика. API постраничное.

getFilms = (str) => {
    fetch(str)
      .then(
          response => response.json()
      ).then(data => {
        ...

        this.setState(prevState => ({
          people: [ ...prevState.people, ...dataArr],
          count: prevState.count + countItems,
          linkSource: data.next
        }));
      })
  };

  getGenderCount = () => {
    let genderCount = {
      male: 0,
      female: 0,
      middle: 0
    };

    let people = this.state.people.slice();

    people.forEach(peopleItem => {
      if (peopleItem.gender === "male") {
        genderCount.male++;
      }
      else if (peopleItem.gender === "female") {
        genderCount.female++;
      }
      else if (peopleItem.gender === "n/a") {
        genderCount.middle++;
      }
    });
    
    this.setState(() => (
      {
        genderCount: {
          male: genderCount.male,
          female: genderCount.female,
          middle: genderCount.middle
        }
      })
    );
  };

  componentDidMount() {
    this.getFilms('https://swapi.co/api/people/');
  }

  componentDidUpdate() {
    this.getGenderCount();

    if (this.state.linkSource && this.state.count < this.state.maxCount) {
      this.getFilms(this.state.linkSource);
    }
  }
  • Вопрос задан
  • 105 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
При обновлении компонента вы вызываете метод getGenderCount, который вызывает setState, в результате чего componentDidUpdate срабатывает ещё раз, снова вызов getGenderCount - setState - compoenentDidUpdate, повторяем до бесконечности (нет, поэтому вы и здесь).

Наверное, вызывать метод getGenderCount следует не при всяком обновлении компонента, а при выполнении каких-то условий (подумайте, каких).

UPD. Как бы мог выглядеть ваш код.
class App extends React.Component {
  state = {
    maxCount: 55,
    people: [],
    url: 'https://swapi.dev/api/people/',
  }

  fetchPeople() {
    fetch(this.state.url).then(r => r.json()).then(r => {
      this.setState(({ people, maxCount }) => ({
        people: [ ...people, ...r.results ].slice(0, maxCount),
        url: r.next,
      }));
    });
  }

  updateGenderCount() {
    this.setState(({ people }) => ({
      genderCount: people.reduce((acc, n) => {
        acc[n.gender] = (acc[n.gender] || 0) + 1;
        return acc;
      }, {}),
    }));
  }

  componentDidMount() {
    this.fetchPeople();
  }

  componentDidUpdate(prevProps, prevState) {
    const count = this.state.people.length;
    if (count !== prevState.people.length) {
      this.updateGenderCount();

      if (this.state.url && count < this.state.maxCount) {
        this.fetchPeople();
      }
    }
  }

  render() {
    return (
      <div>
        <pre>{JSON.stringify(this.state.genderCount, null, 2)}</pre>
      </div>
    );
  }
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы