一言で表すと同じ機能。ではどう使い分ける? useEffectとuseCallbackの使い分け
目次[非表示]
- 1.はじめに
- 2.違いを比較するミニアプリ
- 3.useEffectの基本構造
- 4.useEffectでの実装
- 5.解説
- 6.useCallbackの基本構造
- 7.useCallbackでの実装
- 8.解説
- 9.違いは?
- 10.どんな場面で使用するのがいい?
- 11.終わりに
こちらの記事はDIVXアドベントカレンダー2023の5日目の記事です。
はじめに
こんにちは。名古屋拠点の長屋です。
今回はReactのuseEffectとuseCallbackの使い分けについて書いていこうと思います。
どちらも一言で表すと"着目している値が変化した時に関数を実行させる"機能ですが、どんな時にどちらを使うといいのか、気になったので深掘ってみようと思います。
違いを比較するミニアプリ
ボタンを押すと数字が増えて、数字が偶数の時だけ文字の色が赤くなるアプリを作ります。
useEffect、useCallback、それぞれを使用して作ってみます。
挙動は以下のようになります。
useEffectの基本構造
React Hooksの基本のフックの一つであり、副作用 (effect) フックです。
(副作用とはJSXを返す以外の処理。DOMによる更新、参照や、state(状態)の更新のことです。)
[]に変数などの値を入れて、その値が変化した時に関数を実行できます。
[]に何も入れずに空配列で使用すると、最初の一回だけ実行したい処理を実行できます。
この方法はバックエンドからデータを取得する時などに使われます。
useEffectでの実装
解説
ボタンを押すとonClickによりonClickCountUpが発火します。
onClickCountUpはnum(初期値は0)の値に1を足します。
useEffectは第2引数の値を見張り、変化があったときに第1引数の関数を実行させます。
この場合numの値が変化すると、if文が動いて偶数であると文字が赤くなります。
useCallbackの基本構造
useCallbackは関数のメモ化をします。
関数が毎回呼ばれてしまうのを防ぐことができます。
useEfffectと同じく、[]の値が変化すると第一引数の関数が実行されます。
useCallbackでの実装
解説
ボタンが押されるとnewCountが動き、numに1が足されます。
newCountはsetNumの引数としてsetNumの状態を更新します。
その後、if文が動いて偶数の時に文字色が変化します。
違いは?
画面上の動きは同じですが、コードの仕組みはどこが違うか考えてみました。
- useEffect使用はuseEffect内には色が変わる処理しか入っていない。
- useCallback使用はnum + 1 から色が変わるまでの処理が1つの関数内に入っている。
この違いより、useEffectとuseCallbackをどんな場面で使うと適切か考えてみました。
どんな場面で使用するのがいい?
- useEffect
1度だけ読み込み、または特定の値の変更時が必要な時。
[]に空配列を指定して、データを取得する時に使うのが適切だと考えられます。
例として、記事投稿サイトアプリケーションの記事一覧表示機能部分で使用した例を載せます。
このuseEffect関数は第2引数に空配列を指定しています。つまり着目する値がないのでコンポーネントがマウントされた時に1度だけ第1引数の関数が実行されます。結果として何度もレンダリングすることなく、axios通信を使用してバックエンド(http://localhost:3001/posts )から1度だけデータを読み込んで表示することができます。
- useCallback
関数が何度も使い回される場合、関数化をしておくと便利です。useCallbackを使用することで、関数をメモ化して、再利用することができます。
例えば記事投稿サイトアプリケーションアプリケーションのスレッドのタイトル編集機能を作る際にuseCallbackを使用しました。
第2引数であるupdateTitleが変化したときに、useCallbackによってメモ化された関数handleTitleUpdateが再生成されます。そして、そのhandleTitleUpdateが新しいタイトルを受け取って、updateTitleを経由してタイトルの状態が更新され、それがA.tsxで表示されます。
今回は表示したい場所がA.tsxにあり、B.tsxからhandleTitleUpdateをpropsとして渡す実装をしようとしていました。そのためuseCallbackで関数化して、propsとしてA.tsxに渡すことができました。handleTitleUpdate関数は高頻度で再生成されるのでuseCallbackを使用することでパフォーマンスが向上します。
終わりに
useEffectとuseCallbackは似ていますが、違いを理解しておけばパフォーマンスの高いアプリケーションを作ることができます。
アプリケーション実装中に、”useEffectを使用したけど、この実装はuseCallbackでもできるのでは?”と気づいた場面があったことが今回の記事を書くきっかけです。
今後も、似ている機能に出会った時にとにかくどちらかを使うのではなく、違いを調べてより適切な機能をつけていくように心がけたいです。
divxでは一緒に働ける仲間を募集しています。
興味があるかたはぜひ採用ページを御覧ください。