2021/5/17
React hooksの一種。
第一引数に関数を受け取り、その関数をレンダリングが終了した後に実行する。デフォルトではレンダリングされるたびに毎回実行されます。
第二引数に依存するstateやpropsの配列を入れることで実行に条件をつけることが出来る。具合的には、初回レンダリング時か第二引数に入れたstateやpropsの値が更新された時のみ、第一引数の関数を実行します。
const [state, setState] = useState();
useEffect(()=>{
// レンダリングされるたび実行。
console.log("render")
})
useEffect(()=>{
// 初回レンダリング時とstateが更新されたときのみ実行。
console.log("update state")
}, [state])
初回レンダリング時に動かないようにしたい。
例えば、下記のコードを実行したときに、buttonがクリックされstateが1になったときに初めてuseEffectのconsole.logが実行されてほしい。
const [state, setState] = useState(0);
useEffect(()=>{
// stateに変更があった時だけ動いてほしい!
console.log(state);
}, [state])
return <button onClick={() => {setState(state + 1)}}>Click</button>
useRefを使って、初回レンダリング時はreturnするようにする。
useRefはコンポーネントの存在期間中ずっと存在し続ける変数のようなものです。再レンダリングが行われても値がリセットされることはなく、useStateと違い、値を変更しても再レンダリングされることもありません。
import {useRef} from "react"
const Test = () => {
// refを生成。
const ref = useRef(0);
// .currentで値にアクセスできる。
console.log(ref.current);
return (
<div>
<button
onClick={() => {
// .currentの値を更新
ref.current += 1;
}}>
Click
</button>
<p>
{/* buttonをクリックしても表示が更新されない */}
{ref.current}
</p>
</div>
);
};
}
このような動作をするuseRefを使って、初回レンダリング時のみreturnさせます。
具体的には下記のコードのように、refをtrueで初期化して、初回レンダリング時にref.currentをfalseに変更してreturnさせます。
import { useRef, useEffect, useState } from "react";
const Test = () => {
// refをtrueで初期化。
const ref = useRef(true);
const [state, setState] = useState(0);
useEffect(() => {
// 初回レンダリング時はrefをfalseにして、return。
if (ref.current) {
ref.current = false;
return;
}
// 2回目以降に実行される。
console.log(state);
}, [state]);
return (
<button
onClick={() => {
console.log("clicked");
setState(state + 1);
}}
>
Click
</button>
);
};
複数のuseEffectを使う場合は下のコードのように、一番最後のuseEffectでのみ ref.current = false
として、それ以外のuseEffectではreturnだけをします。
useEffect(()=>{
if(ref.current)return;
console.log("useEffect 1");
}, [state])
useEffect(()=>{
if(ref.current)return;
console.log("useEffect 2");
}, [state])
// 最後のuseEffectなので、ref.current=falseとする。
useEffect(() => {
if (ref.current) {
ref.current = false;
return;
}
console.log("useEffect 3");
}, [state])