Reactガイドを読んでいくその256

これは

Reactのガイドを読んでいく記事です。

ガイドのリンク

ja.reactjs.org

副作用を使う場合のヒント

解説:なぜ副作用は毎回の更新ごとに実行されるのか

クラスの考えでいくとクリーンアップをアンマウントだけでなく再レンダー時に毎回発生するのか不思議に感じる。ここではそれをみていく。

  componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

  componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
      this.props.friend.id,
      this.handleStatusChange
    );
  }

上の例ではthis.propsの中にあるfriend.idを参照してコンポーネントがマウントした後にフレンドステータスを購読し、アンマウント時には購読を解除する。

コンポーネントが表示されている最中にfriendプロパティが変わったらどうなるのか
コンポーネントは間違ったフレンドのオンラインステータスを表示し続ける事になる。

クラスで書いた場合、間違ったフレンドのオンラインステータスを表示し続けるようなバグを避けるため、
componentDidUpdateを加える必要がある。
このcomponentDidUpdateをすることを忘れてしまうのがReactでよくあるバグの一つになっていた。

function FriendStatus(props) {
  // ...
  useEffect(() => {
    // ...
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

フックを利用したバージョンは上のようになる。
動作は変わっておらず前述のバグもおこらなくなる。

useEffectはデフォルトで更新を処理するので、更新のための特別なコードは不要。
一つ前の副作用をクリーンアップをする。
この挙動でデフォルトでよくみられた更新ロジック書き忘れによるバグを防止することができる。

今日はここまで。