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>
);
};