こちらのReactハンズオンラーニングより学ばせていただいたこと内容をまとめています。
useEffectに、名前も機能もよく似たuseLayoutEffectというhookがあり、それについてまとめました。
useEffectとuseLayoutEffectの違い
useLayoutEffectは、コンポーネントの描画サイクルの特定の箇所で呼び出されるhookです。
特定ってなんだよ?
useEffectとuseLayoutEffectを同コンポーネントに記述することにより違いを比較します。
import { useEffect, useLayoutEffect } from "react";
export const UseLayoutEffect = () => {
useEffect(() => console.log("useEffect"));
useLayoutEffect(() => console.log("useLayoutEffect"));
return <div>ready</div>;
};
import { UseLayoutEffect } from "./components/UseLayoutEffect";
function App() {
return (
<>
<UseLayoutEffect />
</>
);
}
export default App;
こちらのコンソールの出力結果は以下のようになります。
useLayoutEffect
useEffect
useLayoutEffectの方が先に出力されます。
これはなぜでしょう?
useLayoutEffectで設定された副作用が実行されるタイミングは、コンポーネントの描画関数が呼ばれるよりも後。これはuseEffectと同じです。
この後が異なります。
useLayoutEffectは、描画結果が画像に表示されるよりも前。
useEffectは画像に表示された後。
つまり、useEffectは、描画が画像に反映される前に処理を実行したい場合に使います。
実行順を整理するとこうなります。
useEffect
コンポーネントの描画関数(returnの後)呼び出し → 画面表示 → useEffectの関数実行
useLayoutEffect
コンポーネントの描画関数(returnの後)呼び出し → useEffectLayoutの関数実行 → 画面表示
実用例
実用例として、マウスの座標を追跡するカスタムフックを作ってみます。
import { useState, useLayoutEffect } from "react";
function useMousePosition() {
const [x, setX] = useState(0);
const [y, setY] = useState(0);
const setPosition = ({ x, y }) => {
setX(x);
setY(y);
};
useLayoutEffect(() => {
// マウスを動かしたときにsetPositionが発動する
window.addEventListener("mousemove", setPosition);
// setPositionを解除
return () => window.removeEventListener("mousemove", setPosition);
}, []);
return [x, y];
}
この場合、順番としては、
- [x, y]が呼び出される
- useLayoutEffect内の関数が呼び出される
- 2での処理結果が、画面に反映される
useEffectの場合だと、画面に反映された後にuseEffectの処理結果が返ってくるため表示されない。
useLayoutEffectの使い所を習得することができました。
以上、読んでいただきありがとうございました。
コメント