一言でいうと描画が完了した後に処理を実行するもの
です
描画が完了 = 初期のロード時だけではなく、props
やstate
が変更されたときにもコンポーネントが再構築される時も入る
useEffect は毎回のレンダー後に呼ばれるのか? その通りです! デフォルトでは、副作用関数は初回のレンダー時および毎回の更新時に呼び出されます。
出典: 公式
使い方は以下
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
文言を書き換えてます
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
useEffectの第一引数には実行したい処理を入れますが、第二引数には配列を入れることができます。
この配列には依存したい値を入れることになっており、例えばstateの値を入れたりして使います。
再レンダー間で特定の値が変わっていない場合には副作用の適用をスキップするよう、React に伝えることができるのです。そのためには、useEffect のオプションの第
2
引数として配列を渡してください。
useEffect(() => {
// countの値が更新された時に処理を実行
document.title = `You clicked ${count} times`;
},[count]);
上記の例では、第
2
引数として [count] を渡しています。どういう意味でしょうか? もし count が 5 で、次回のコンポーネントのレンダー時にも count がまだ 5 であった場合、React は前回のレンダー時に覚えておいた [5] と今回のレンダーの [5] とを比較します。配列内のすべての要素が同一 (5 === 5) ですので、React は副作用をスキップします。これが最適化です。
また空の配列を渡すと初期ロード時のみ処理を走らせることができます。
useEffect(() => {
// ロード時のみ処理を実行
document.title = `You clicked ${count} times`;
},[]);
あと絶対誰もがやること紹介します。
const [obj, setObject] = useState({});
useEffect(() => {
setObject({ hoge: "hoge" });
}, [obj]);
上記はobjというオブジェクトが更新された時にobjを更新するというコードなのですが、これは無限ループになります。
開発者ツールのコンソール画面で以下のように
{hoge: "hoge"} === {hoge: "hoge"}
と打ってもらうとfalseが帰ってきます。
対処方法については以下の記事がわかりやすくまとまっていました
参考: