Реакция - утечка памяти, проблемы с ComponentWillUnmount / Axios - PullRequest
0 голосов
/ 01 марта 2020

Я выполняю вызов API, который запускается с помощью componentDidMount, однако, когда пользователь загружает новый компонент, появляется уведомление о потенциальной утечке памяти, сообщение см. Ниже. Я исследовал различные решения, но пока не нашел ничего, что работает, мне интересно, можно ли это исправить в этом конкретном компоненте с помощью componentWillUnmount или лучше обрабатывать в самом вызове ax ios.

Невозможно выполнить обновление состояния React для отключенного компонента. Это неоперация, но она указывает на утечку памяти в вашем приложении. Для исправления отмените все подписки и асинхронные задачи в методе componentWillUnmount.

componentDidMount() {
    this.loadBackground();
    this.getUpdatedWeather();
    this.getNewMartianPhotos();
  }

  checkMartianPhotos = () => {
    if (this.state.martianMotion) {
      console.log('still shooting');
      this.getNewMartianPhotos();
    } else {
      return console.log('done now');
    }
  };

  getNewMartianPhotos = () => {
    let loadedImage = '';
    let loadedInfo = '';
    let loadedMeta = '';
    let totalImage;

    API.getMarsPhotos().then(data => {
      // console.log(data.data);
      // console.log(
      //   data.data.collection.items[this.state.martianCount].data[0].photographer
      // );
      // console.log(
      //   data.data.collection.items[this.state.martianCount].data[0].description
      // );
      // console.log(
      //   data.data.collection.items[this.state.martianCount].links[0].href
      // );

      totalImage = data.data.collection.items.length;
      loadedImage =
        data.data.collection.items[this.state.martianCount].links[0].href;
      loadedInfo =
        data.data.collection.items[this.state.martianCount].data[0].description;
      loadedMeta =
        data.data.collection.items[this.state.martianCount].data[0]
          .photographer;

      this.setState({
        martianImage: loadedImage,
        martianDescription: loadedInfo,
        martianMeta: loadedMeta,
        martianCount: this.state.martianCount + 1
      });

      if (this.state.martianCount < totalImage) {
        console.log(
          `shooting off, image count now ${this.state.martianCount} against ${totalImage}`
        );
        setTimeout(this.checkMartianPhotos, 10000);
      }
    });
  };

  componentWillUnmount() {
    clearTimeout(this.checkMartianPhotos);
  }


-------------------------------------

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

  getMarsPhotos: () =>
    axios
      .get('https://images-api.nasa.gov/search?q=martian', {
        cancelToken: source.token
      })
      .catch(function(thrown) {
        if (axios.isCancel(thrown)) {
          console.log('request canceled', thrown.message);
        } else {
          console.log('there is an error that needs to be handled');
        }
      })

1 Ответ

0 голосов
/ 01 марта 2020

Как сообщает ошибка, ваш компонент вызывает setState после его размонтирования. Это потому, что вы неправильно очищаете время ожидания. Чтобы правильно сбросить время ожидания при размонтировании, вы должны сделать следующее:

this.id = setTimeout(this.checkMartianPhotos, 10000);

А затем очистить с помощью

clearTimeout(this.id)

В componentWillUnmount

Также попробуйте переместить asyn c logi c (вызовы API) из вашего компонента.

Обратитесь к this , чтобы узнать, как прекратить установку состояния после вызова API на размонтированном компоненте.

...