React HookのuseEffectはどのようなときに使うの?
useEffectはレンダリングの後に実行したい処理があるときに使うよ!
Hookとは?
Hook(フック)とはReact 16.8のバージョンで新しくで追加された機能です。
Hookは関数コンポーネントで使うことができる機能で、クラスを書かなくてもstateなどの機能を使えるようになります。
useEffectはHookの1つの機能です。
useEffectとは?
「useEffect
」は関数のタイミングをレンダリングされた後まで遅らせるフックです。
useEffectで実行される処理ははレンダーの結果が画面に反映された後になります。
useEffectのEffectは「Side Effect = 副作用」を意味しています。
副作用の処理には「DOMの操作」、「ロギング」、「API通信」などが該当します。
また副作用には 2 種類あり、クリーンアップを必要としない副作用と、必要とする副作用があります。
クリーンアップとはイベントリスナの削除やタイマーのキャンセルなどを指します。
クリーンアップを必要としない副作用として使うことが多いですが、クリーンアップを必要とする処理についても解説していきます。
useEffectの処理はクラスコンポーネントでのライフサイクルメソッドに該当し同様な処理を行います。
クラスコンポーネントの3つのライフサイクルの名前よりuseEffectではどのような処理ができるのかイメージすることができます。
componetDidMount
- コンポーネントのマウント直後に実行される
componentDidUpdate
- コンポーネントが再レンダリングされる度に実行される
comonentWillUnmount
- コンポーネントがアンマウントされて破棄される直前に実行される
useEffectは状態の変化によって関数を実行させるときによく使われるのでuseStateと一緒に用いられることが多いです。
useStateの詳しい使い方はこちらを参照してください。
useEffectの使い方
まずはuseEffectの機能をインポートします。
インポートしなくても使えますが、 今回はインポートをして使っていきます。
import React, { useEffect } from 'react';
インポートができたらuseEffectを使うことができるようになります。
useEffect(() => {
/* 第1引数には任意のタイミングで実行させたい関数を記述 */
},[変数の配列]) // 第2引数には第1引数の関数を実行するタイミングを制御する変数を配列で記述
第2引数を指定することで、配列の中に格納されている変数のいずれかひとつでも前回のレンダリング時と比較して差分(変化)があれば、第1引数の関数が実行されます。
useStateなどのsteteの状態によって関数を実行したいときよく使われます。
また第2引数は省略も可能です。
シンプルにuseEffectを使う(第2引数を省略)
useEffectの第2引数を省略すると、第1引数に記述した関数はコンポーネントがレンダリングされる度に実行されます。
useEffect(() => {
console.log('useEffectを実行しました。');
})
第2引数を省略するとコンポーネントがレンダリングされる度に、第1引数に記述した関数が実行されるため無限ループ処理になってしまうことがあり注意が必要です。
実際には第2引数を省略するケースはほとんありません。
import React, { useState, useEffect } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('useEffectを実行しました。');
})
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
例えば上記のソースコードの「+」や「-」ボタンをクリックする度にuseEffectが実行されます。
1度だけuseEffectを実行させる(第2引数を空にする)
関数を1度だけ実行させたいときは、第2引数に空の配列([]
)を指定します。
useEffect(() => {
console.log('useEffectを実行しました。');
}, [])
空の配列を指定することで最初のレンダリングの1度のみ関数が実行されます。
import React, { useState, useEffect } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('useEffectを実行しました。');
}, [])
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
初回の1度のみuseEffectが実行されるので、例えば上記のソースコードの「+」や「-」ボタンをクリックしたとしてもuseEffectは実行されません。
また、この方法はAPI呼び出しのときにも使われます。
同じリクエストを複数回呼ばれることを防ぐことができます。
stateの状態でuseEffectを実行させる(第2引数を指定する)
状態の変化によってuseEffectを実行したいときは第2引数の配列の中に状態の変化を管理しておきたい変数を指定します。
この変数はuseStateで作成したstateの変数を指定します。
useEffect(() => {
console.log('useEffectを実行しました。');
}, [count])
変数を指定することでstateの変数に変化があったときにuseEffectが実行されます。
他のレンダリングがあったとしても、stateの変数に変化がないときはuseEffectは実行されません。
import React, { useState, useEffect } from 'react';
export const Count = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('useEffectを実行しました。');
}, [count])
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
例えば上記のソースコードの「+」や「-」ボタンをクリックすることでsetCount
関数が実行されcount変数が更新されるので、その度にuseEffectが実行されます。
stateの変化によって実行したい関数があるときに便利な方法です。
クリーンアップをする方法
クリーンアップとはイベントリスナーの削除やタイマーをキャンセルして前回の副作用を削除することです。
リクエストの送信や DOM操作、ログの記録は、処理を実行した後すぐにそのことを忘れても構わないため、クリーンアップを必要としない副作用となります。
しかし、イベントリスナーやタイマー処理をしたときは、その処理をキャンセルしないと処理が続いてしまうためキャンセルをするクリーンアップが必要になります。
クリーンアップするときはreturn
でイベントリスナーの削除やタイマーをキャンセルする関数を返します。
useEffect(() => {
element.addEventListener('click', () => { // イベント処理 })
return () => {
element.removeEventListener('click', () => { // イベント処理 }) // イベントリスナーの削除(クリーンアップ)
}
}, [])
useEffect(() => {
const interval = setInterval(() => {
setCount(count => count + 1);
}, 3000)
return () => {
clearInterval(interval); // タイマーの削除(クリーンアップ)
}
}, [])
クリーンアップをするための関数はコンポーネントがアンマウント(解除)されるときに実行されます。
副作用は 1 回だけではなく、レンダリングされる度に毎回実行されます。
そのため、新しい副作用が実行される前にクリーンアップが行われ、その後に次回の副作用が実行されていきます。
このように、マウント処理やアンマウント処理のライフサイクルに気を付けて処理をする必要があるケースもあるので注意をしましょう。
まとめ
React HookのuseEffectの使い方について解説したよ!
- useEffectは関数のタイミングをレンダリングされた後まで遅らせるフック
- 副作用にはクリーンアップを必要としない副作用と、必要とする副作用の2 種類がある
- useEffectの第1引数に記述した関数が実行されるタイミングは第2引数の扱い方によって変わる
useEffectどのようにして使うのか分かったよ!