見出し画像

React Hooksとカスタムフック

React Hooksとは?

React HooksはReact 16.8で追加された機能で、関数型コンポーネントで状態管理やコンポーネントのライフサイクルに応じた処理を行うことができ、ReactでWebアプリケーションを開発する上では必須の機能と言える。

基本的なフック

useState

関数型コンポーネントで状態を管理できるフック。

import { useState } from "react";

// state: 状態の変数
// setState: 状態を更新する関数
// initState: 状態の初期値
const [state, setState] = useState(initState);

useEffect

関数型コンポーネントで副作用(外部データの取得など)を実行できるフック。

import { useEffect } from "react";

// 第1引数: 副作用の処理
// 第2引数: 依存配列。指定した変数が更新されると副作用が実行される。
useEffect(() => {
    // 副作用の処理
    // ...
    return () => {
        // クリーンアップ処理
    }
}, []);

補足:依存配列に空配列を指定することで、初回レンダリング時のみ実行できたが、React 18からstrictモードの動作仕様の変更により、開発時に2回実行されるようになった。これは将来的な機能導入のための対応(こちらを参照)で、副作用が複数回実行されてもいいように対応した方がいいだろう。

React.memo

関数コンポーネントをメモ化(計算結果を保持して再利用する方法)するフック。コンポーネントに渡されるpropsの値に変化がない場合は、再レンダリングを回避できる。

import { memo } from "react";

const MyComponent = memo((props) => {
    // レンダリング処理
})

useCallBack

関数をメモ化するフック。依存配列で指定した変数が更新されない限り、関数の計算結果を再利用できる。

import { useCallBack } from "react";

// 第1引数: 関数
// 第2引数: 依存配列。指定した変数が更新されるとメモ化した値を再計算する。
const memoizedCallback = useCallback(() => {
  doSomething(a, b);
}, [a, b]);

React.memoとuseCallBackを併用すれば、不要なコンポーネントの再レンダリングや関数の再実行を回避でき、パフォーマンス向上に繋がる。
他にも様々なフックがあり、詳しくは公式ドキュメントを参照。

カスタムフック

カスタムフックとは、useXXXのような名前で他のフックを呼び出せる関数のことで、カスタムフックを作ることで、コンポーネントからロジックを切り出して再利用できる(公式ドキュメント参照)。

サンプルコード

JSONPlaceholderからユーザー一覧を取得するサンプルコード。ユーザー一覧の取得処理をuseUsersとして切り出し、コンポーネント内で呼び出して取得されたユーザー一覧を表示する。

import { useState, useEffect } from "react";

export const useUsers = () => {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    const fetchUsers = async () => {
      const response = await fetch("<https://jsonplaceholder.typicode.com/users>");
      const data = await response.json();
      setUsers(data);
    };

    fetchUsers();
  }, []);

  return { users };
};
import { useUsers } from '../hooks/useUsers';

export const User = () => {
  const { users } = useUsers();

  return (
    <div>
      <h1>ユーザ一覧</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
};

参考


この記事が気に入ったらサポートをしてみませんか?