componentDidUpdateをuseEffectで書き換える方法

Reactは、仮想DOMなど、いくつかの重要なコンセプトをフロント開発にもたらしました。

 

これにより、私たちは常にコードを改善し、より保守性の高いアプリケーションを作ることができるようになりました。

 

そしてReactの最も重要な機能(Reactコア自体に組み込まれているもの)と言えば、

 

Reactコンポーネントのライフサイクルとライフサイクルメソッドですよね。

 

今回の記事では、Reactのライフサイクルを、最新のhooks apiを使って書き換える方法をお伝えします。

 

コンポーネントのライフサイクルとライフサイクルメソッド

 

各Reactコンポーネントにはそれぞれのステージがあり、

 

これらのステージはReactコンポーネントのライフサイクルとして知られています。

 

Reactコンポーネントのライフサイクルには、

 

いくつかの異なる段階がありますので、見てみましょう。

 

Mounting

これはReactコンポーネントの最初のライフサイクルで、

 

コンポーネントが作成され、DOMに挿入される段階です。

 

このライフサイクルの段階では、

 

componentDidMountライフサイクルメソッドがあります。

 

componentDidMountライフサイクルメソッドは、

 

コンポーネントがマウントされたときに発生します。

 

 

componentDidMount() {
  console.log("The component has mounted successfully!");
  this.setState({
    loaded: true
  })
}

 

componentDidMountではsetStateを使うことができるので、

 

このライフサイクルメソッドで簡単に状態を設定したり変更したりすることができます。

 

このライフサイクルメソッドは、APIコールを実行したり、

 

リモートエンドポイントへの呼び出しを行ったり、

 

データを取得したりするために使用します。

 

Updating

 

このライフサイクルステージは、コンポーネントがマウントされ、DOMにレンダリングされた後に起こります。

 

Reactコンポーネントは、props や state.に更新があると更新されます。

 

この特定のライフサイクルで使用できるものは、

 

shouldComponentUpdateやcomponentDidUpdateなどのライフサイクルメソッドがあります。

 

shouldComponentUpdateのライフサイクルメソッドはとてもシンプルで

 

コンポーネントReactがコンポーネントを更新すべきかどうかを判断するために、

 

ブール値を返すだけで、このメソッドのデフォルト値はtrueです。

 

shouldComponentUpdate() {
  return true;
}

 

componentDidUpdateライフサイクル・メソッドは、

 

コンポーネントで更新が起こった後に呼び出されます。

 

このライフサイクル・メソッドは、

 

特定のプロップやステートが変更されたかどうかを比較するために使用されます。

 

componentDidUpdate(prevProps) {
  if (this.props.name !== prevProps.name) {
    console.log("Name has changed!");
  }
}

 

Unmouting

 

このライフサイクルは、DOMのクリーンアップを行う責任があります。

 

特に、コンポーネントをDOMから削除したい場合、Reactではこれをアンマウントと呼びます。

 

このライフサイクルステージにはcomponentWillUnmountというライフサイクルメソッドが1つだけあり、

 

コンポーネントがDOMから削除されようとしているときに呼び出されます。

 

componentWillUnmount() {
  console.log("Component unmounted!");
}

 

非推奨のライフサイクルメソッド

 

Reactバージョン16.3.0では、いくつかのライフサイクルメソッドが廃止されました。

 

廃止されたライフサイクルメソッドは以下の通りです。

 

componentWillMount
componentWillReceiveProps
componentWillUpdate

 

これらのライフサイクルメソッドが廃止された主な理由の1つは、

 

Reactが非同期レンダリングを実装した際に、これらのライフサイクルメソッドの1つを誤って使用すると、

 

大きなエラーが発生したり、安全でないコーディングプラクティスを助長したり、

 

状況によってはメモリリークが発生したりする可能性があったためです。

 

では、どう変わるか

 

新しいReactの機能では、副作用を実行できるようにするために、

 

ReactチームはuseEffect Hookを作成しました。

 

useEffect Hookは、Functionコンポーネントで副作用を実行することを可能にします。

 

useEffect Hookの仕組みを説明します。

 

まず、Reactからインポートする必要があります。

 

import { useEffect } from "react";

 

コンポーネントではuseEffect Hookを呼び出します。

 

useEffect(() => {
// このコールバック関数の中で、サイドエフェクトを実行します。
});

 

このコールバック関数が「エフェクト」となり、呼び出されることになります。

 

useEffect Hookは、コンポーネントがレンダリングされるたびに呼び出されるため、2番目の引数を用意しています。

 

useEffect Hookは、第2引数として、依存関係の配列を受け取ります。

 

この配列の中には、useEffect Hookが監視する依存関係を渡すことができます。

 

依存関係の配列をバイパスすることで、useEffect Hookはこれらの依存関係の1つが変更された場合にのみ実行されます。

 

つまり、usernameというプロップがあるとします。

 

このプロップを依存関係としてuseEffectフックに渡すと、usernameプロップが変更された場合にのみ実行されます。

 

useEffect(() => {
  // 依存関係の配列を渡すと、依存関係の1つが変更された場合にのみ useEffect フックが実行されます。
}, [name]);

 

useEffect Hookに空の配列を渡すと、レンダリング後に一度だけ実行されます。

 

Reactのドキュメントでは、useEffect Hookの基本的な説明はこうなっています。

 

Reactのクラスライフサイクルメソッドに慣れている方は、useEffect HookをcomponentDidMount、componentDidUpdate、componentWillUnmountを組み合わせたものと考えることができます。

 

useEffect Hookのおかげで、副作用の実行がとても簡単になりました。

 

今回のケースでは、いくつかのライフサイクル・メソッドに相当するものを実行してみましょう。

 

Reactの既存機能をuseEffectで置き換える

 

componentDidMount

useEffectフックを使って、componentDidMountと同等の処理を行う方法です。

 

useEffect(() => {
// このコールバック関数の中で、サイドエフェクトを実行します。
});

 

useEffect フックを呼び出してコールバック関数を渡すだけで、

 

componentDidMount ライフサイクル メソッドと同等の処理を行うことができます。

 

とても簡単ですね。

 

componentDidUpdate

 

useEffectフックを使ってcomponentDidUpdateと同等の処理を行うには、

 

次のようにします。

 

useEffect(() => {
// このコールバック関数の中で、サイドエフェクトを実行します。
}, [dependency]);

 

これで終わりです。

 

先ほどとほぼ同じですが、今回は2番目のパラメータとして依存関係の配列を渡し、

 

その配列の中に、監視したい依存関係を渡します。

 

もし依存関係を渡さなかった場合、

 

useEffect HookはcomponentDidUpdateライフサイクルメソッドとして機能します。

 

componentWillUnmount

 

コンポーネントがアンマウントされた後の後始末をするために、

 

useEffect Hookを使ってcomponentWillUnmountと同等の処理を行う簡単な方法があります。

 

必要なことは、useEffect Hookのコールバック関数の中で、次のように関数を返すことだけです。

 

useEffect(() => {
  window.addEventListener("mousemove", () => {});
  return () => {
    window.removeEventListener("mousemove", () => {})
  }
}, []);

 

これで終わりです。

 

非常にシンプルで、クラスコンポーネントにあるライフサイクルメソッドと同様のサイドエフェクトを、

 

useEffect Hookを使って、きれいでわかりやすいコードで実行することができます。

 

Dan Abramov氏は2019年5月に「A Complete Guide to useEffect」という記事を書いています。

 

この記事を読み終わった後に、彼の記事を読むことをぜひお勧めします。

 

React Hooksが使えるようになった今、もうクラスコンポーネントを使う必要はなく、

 

今日から簡単にクラスコンポーネントのすべてを機能コンポーネントに移行することができますし、

 

ライフサイクルメソッドがまだ移行していない唯一の理由の1つだったのであれば、

 

今は安全に機能コンポーネントに移行して、

 

アプリケーションでReact Hooksを使うことができます。

 

[st-minihukidashi fontawesome=”” fontsize=”” fontweight=”” bgcolor=”#FFB74D” color=”#fff” margin=”0 0 20px 0″ radius=”” add_boxstyle=””]今回の記事は、下記の記事を参考に、分かりやすい部分だけ抜粋して翻訳してお届けしました。[/st-minihukidashi]

 

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です