web-dev-qa-db-ja.com

reactでx秒ごとにapiをポーリングする

画面上のデータ更新情報を1〜2秒ごとに監視する必要があります。私がこの実装を使用していたと思った方法:

componentDidMount() {
    this.timer = setInterval(()=> this.getItems(), 1000);
  }

  componentWillUnmount() {
    this.timer = null;
  }

  getItems() {
    fetch(this.getEndpoint('api url endpoint"))
        .then(result => result.json())
        .then(result => this.setState({ items: result }));
  }

これは正しいアプローチですか?

25
Eduardo Spaki

まあ、あなたはAPIしか持っておらず、ソケットを使用するように変更するためにAPIを制御できないので、あなたが持っている唯一の方法はポーリングすることです。

あなたのポーリングが懸念しているように、あなたはまともなアプローチをしています。しかし、上記のコードには1つの落とし穴があります。

_componentDidMount() {
  this.timer = setInterval(()=> this.getItems(), 1000);
}

componentWillUnmount() {
  this.timer = null; // here...
}

getItems() {
  fetch(this.getEndpoint('api url endpoint"))
    .then(result => result.json())
    .then(result => this.setState({ items: result }));
}
_

ここでの問題は、コンポーネントがアンマウントされると、_this.timer_に保存した間隔への参照はnullに設定されますが、まだ停止されないことです。この間隔は、コンポーネントがアンマウントされた後でもハンドラーを呼び出し続け、存在しないコンポーネントでsetStateを試行します。

適切に処理するには、最初にclearInterval(this.timer)を使用し、次に_this.timer = null_を設定します。

また、fetch呼び出しは非同期であるため、同じ問題が発生する可能性があります。 キャンセル可能 にし、fetchが不完全な場合はキャンセルします。

これがお役に立てば幸いです。

31
Dangling Cruze