useEffectは関数が実行されるタイミングをレンダリングの後にすることができるHookで、APIからデータを取得して表示させる場合によく使われます。
コンポーネントが最初に読み込まれたときだけ実行、特定のステートに変化があったときのみ実行するなどの対応が可能となります。
Contents
レンダリング毎にuseEffectが実行されるケース
まず、ボタンをクリックするとクリック数が表示されるプログラムを作り、useEffectも記載してみます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import React from 'react' import { useState , useEffect } from 'react' const UseEffect_Test = () => { const[count , setCount] = useState(0) //基本的にレンダリングの直後に実行される。 useEffect(() => { console.log ("ログの出力") } ) return ( <div> <button onClick={()=> setCount(prevCount =>prevCount +1)}> クリックカウント: {count} </button> </div> ) } |
ボタンを押すとブラウザのコンソールにログが出力されます。クリックされる毎にログが出力されているのがわかります。
初回ローディング時のみにuseEffectが実行されるケース
useEffect関数のポイントは第二引数にあります。
上記のプログラムを以下のように変えてみます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const UseEffect_Test = () => { const[count , setCount] = useState(0) //useEffectに第二引数を設定(空の配列) useEffect(() => { console.log ("ログの出力") },[] ) return ( <div> <button onClick={()=> setCount(prevCount =>prevCount +1)}> カウント回数: {count} </button> </div> ) } export default UseEffect_Test |
このように変えると、ページを読み込んだときだけログが出力されます。それ以降はボタンを押す毎にカウントは増えていきますが、ログは出力されません。
特定の変数の値が変化したときのみ反応するケース
今度は2つのカウントアップボタンを作ってみます。左側は押してもログを出力しない、右は押されるたびにログを出力するプログラムです。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import React from 'react' import { useState , useEffect } from 'react' const UseEffect_Test = () => { const[count , setCount] = useState(0) const[countB , setCountB] = useState(0) //useEffectに第二引数を設定(空の配列) useEffect(() => { console.log ("ログの出力") },[count] ) return ( <div> <button onClick={()=> setCount(prevCount =>prevCount +1)}> カウント回数: {count} </button> <button onClick={()=> setCountB(prevCount =>prevCount +1)}> カウント回数B: {countB} </button> </div> ) } export default UseEffect_Test |
useEffectの第二変数に、反応させたい変数を指定します。今回はcountB(右側のボタン)に反応します。
初回ローディングのときにログが出力されます。その後は右側のボタンを押したときだけログが出力されます。左右のボタン共にクリックするとカウント数は増加します。
useEffectのクリーンアップ
useEffectにはコンポーネントアンマウント時・次のHookが開始する前に実行されるクリーンアップ機能があります。
0 1 2 3 4 5 6 7 8 9 10 |
useEffect(() => { const t = setTimeout(() => { console.log('1秒経過'); }, 1000); return () => { clearTimeout(t); }; }, []); |
return()でクリーンアップを設定します。タイマーが動き続けてしまうのを止めることができます。