Hooks

React の関数コンポーネントに状態管理や副作用などの機能を追加する仕組み

Reactフロントエンド

Hooks とは

Hooks は React 16.8 で導入された仕組みで、関数コンポーネントに状態管理、副作用、コンテキストなどの機能を追加する。クラスコンポーネントの this.statecomponentDidMount を置き換え、ロジックの再利用を容易にした。

基本の Hooks

useState

function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

useEffect

function UserProfile({ userId }: { userId: string }) {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(setUser);
  }, [userId]); // userId が変わるたびに実行

  return user ? <div>{user.name}</div> : <div>Loading...</div>;
}

useRef

function TextInput() {
  const inputRef = useRef<HTMLInputElement>(null);
  return (
    <>
      <input ref={inputRef} />
      <button onClick={() => inputRef.current?.focus()}>Focus</button>
    </>
  );
}

Hooks の一覧

Hook 用途
useState 状態管理
useEffect 副作用 (API 呼び出し、DOM 操作)
useRef DOM 参照、値の保持 (再レンダリングなし)
useMemo 計算結果のメモ化
useCallback 関数のメモ化
useContext コンテキストの参照
useReducer 複雑な状態管理 (Redux 的)
useId サーバー/クライアントで一致する ID 生成

カスタム Hook

ロジックを再利用可能な関数に抽出する。

function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(res => res.json())
      .then(setData)
      .catch(setError)
      .finally(() => setLoading(false));
  }, [url]);

  return { data, loading, error };
}

// 使用
function UserList() {
  const { data: users, loading } = useFetch<User[]>('/api/users');
  if (loading) return <div>Loading...</div>;
  return <ul>{users?.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

Hooks のルール

  1. トップレベルでのみ呼び出す (条件分岐やループの中で呼ばない)
  2. React の関数コンポーネントまたはカスタム Hook 内でのみ呼び出す
// ❌ 条件分岐の中で呼んではいけない
if (isLoggedIn) {
  const [user, setUser] = useState(null); // ❌
}

// ✅ トップレベルで呼ぶ
const [user, setUser] = useState(null);

よくある間違い

  • useEffect の依存配列を空にして、古い値を参照し続ける (stale closure)
  • useEffect 内で無限ループを起こす (依存配列にオブジェクトを入れる)
  • useMemo / useCallback を不要な箇所で使い、かえって複雑にする

全体像を把握するには関連書籍も有用。

関連用語