1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Reactのフック(useEffect,useLayoutEffect,useReducer,useMemo,useCallback)

Posted at

はじめに

  • useState、useContext以外の重要なフック群。
  • useEffectとuseLayoutEffectはコンポーネントのライフサイクルに組み込まれており、特定のタイミングで初期化やアンマウントなどを行える。
  • useMemoやuseCallbackはパフォーマンスチューニングで使用する
    • ただし、ロジックが複雑になるので乱用はしないこと
  • useReducerはuseStateの更新部分を抽象化する。

useEffect

  • 副作用となる処理を記述する
    • 副作用は描画の一部ではない処理
    • コンポーネント描画後に行われるので、非同期処理等(API)
  • 依存配列
    • 副作用が実行される条件を記述する
    • 記載しない場合、再レンダリングの度に実行される
    • 空配列の場合、初期描画時のみ実施
  • 戻り値
    • コールバック関数を返すことで、アンマウント時の処理を行える
  useEffect(() => {
    console.log('再レンダリング時実行');
  });

  useEffect(() => {
    console.log('初期化時');
    return () => console.log('アンマウント時');
  }, []);

  useEffect(() => {
    console.log(`val変更時: ${val}`);
  }, [val]);

useLayoutEffect

  • useEffectよりも前に呼び出される

    • useEffectは、画面描画後だが、useLayouEffectは画面描画前
    • 画面描画前に取得したい情報:画面サイズやマウス座標等を取得する際に利用する
  • 以下、マウス座標を取得するフック関数

import { useLayoutEffect, useState } from 'react';

export const useMousePosition = () => {
  const [x, setX] = useState(0);
  const [y, setY] = useState(0);

  const setPosition = ({ x, y }) => {
    setX(x);
    setY(y);
  };

  // 初期化時、アンマウント時のイベントリスナー
  useLayoutEffect(() => {
    window.addEventListener('mousemove', setPosition);
    return () => window.removeEventListener('mousemove', setPosition);
  }, []);

  return [x, y];
};

利用
export const Render = () => {
  const [x, y] = useMousePosition();
  return (
    <>
        <span>{`x:${x},y:${y}`}</span>
    </>
  );
};

useMemo

  • 依存配列が配列やオブジェクト等の参照値だった場合、その値を変更しても同一だとみなされず、毎回レンダリングされてしまう。
  • その場合、useMemoを使用する
const words = useMemo(() => childeren.split(' '), [childeren]);

useEffect(() => {
    console.log('fresh render');
}, [words]);

useCallback

  • useMemoと同様の機能で、関数の場合はこちら
  // 初期化時のみ
  const fn = useCallback(() => {
    console.log('function!');
  }, []);

  useEffect(() => {
    console.log('rendaring');
    fn();
  }, [fn]);

useReducer

  • useStateのかわりに使用する。戻り値にstateの初期値と、更新関数を返す。
  • stateの更新ロジック定義時に記載することで抽象化できる。
state→reducerへ
// state
-export const Numbers = () => {
-  const [number, setNumber] = useState(0);
-  // useStateの場合、更新ロジックは使用する際に記載する。
-  return <h1 onClick={() => setNumber((number) => number + 1)}>{number}</h1>;
-};

// reducer
+export const Numbers = () => {
+  // reducerの場合、定義時に記載する。
+  const [number, setNumber] = useReducer(
+    (number, newNumber) => number + newNumber,
+    0
+  );
+  return <h1 onClick={() => setNumber(1)}>{number}</h1>;
+};

フック関数の注意点

  • コンポーネント内、またはカスタムフック内で呼び出すこと
  • 関数のトップレベルから呼び出す
    • 条件文や、ループ、ネストした関数では呼び出さない
    • やりたい場合は、フック関数内で行う
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?