React 速習チュートリアル

React Custom Hooks

自分専用の Hook(フック)を作成することができます!

複数のコンポーネントで再利用できるロジックがある場合、そのロジックを「カスタムフック(Custom Hook)」として抽出することが可能です。

カスタムフックの名前は必ず "use" で始める必要があります(例:useFetch)。

1. カスタムフックを構築する

まずは、カスタムフックを使用しない場合の例を見てみましょう。
以下のコードでは、URL からデータをフェッチ(取得)して表示しています。
ここでは、ダミーデータを取得するために JSONPlaceholder サービスを利用します。

※ データのフェッチに関する詳細は、「JavaScript Fetch API」のセクションを参照してください。

1.1 実装例

JSONPlaceholder サービスを使用してダミーのタイトルを取得し、表示します。

import { useState, useEffect } from 'react';
import { createRoot } from 'react-dom/client';

const Home = () => {
  const [data, setData] = useState(null);

  useEffect(() => {
    // APIからデータを取得
    fetch("https://jsonplaceholder.typicode.com/todos")
      .then((res) => res.json())
      .then((data) => setData(data));
  }, []);

  return (
    <>
      {data &&
        data.map((item) => {
          return <p key={item.id}>{item.title}</p>;
        })}
    </>
  );
};

createRoot(document.getElementById('root')).render(
  <Home />
);

このフェッチ処理のロジックは他のコンポーネントでも必要になる可能性があるため、これをカスタムフックに変換してみましょう。

2. フェッチロジックの抽出

フェッチロジックを新しいファイルに移動し、カスタムフックとして使用できるようにします。
ファイル名は必ず use で始まり、拡張子は .js(または .jsx)である必要があります。また、通常はコンポーネントと同じディレクトリに配置します。

ここでは、ファイル名を useFetch.js とします。

2.1 useFetch.js

フェッチコンポーネント(ロジック)を新しいファイルに移動します。

import { useState, useEffect } from "react";

const useFetch = (url) => {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then((res) => res.json())
      .then((data) => setData(data));
  }, [url]); // urlが変更された時に再実行

  return [data];
};

export default useFetch;

3. カスタムフックの使用

これで、作成したフックをインポートし、他のどのコンポーネントからでも利用できるようになります。

3.1 main.jsx

新しく作成したカスタムフックをインポートして使用します。

import { createRoot } from 'react-dom/client';
import useFetch from "./useFetch";

const Home = () => {
  // カスタムフックを利用してデータを取得
  const [data] = useFetch("https://jsonplaceholder.typicode.com/todos");

  return (
    <>
      {data &&
        data.map((item) => {
          return <p key={item.id}>{item.title}</p>;
        })}
    </>
  );
};

createRoot(document.getElementById('root')).render(
  <Home />
);

4. 実装の解説

今回のリファクタリング(再構築)では、以下のことを行いました。

  • useFetch.js という新しいファイルを作成し、データのフェッチに必要なすべてのロジックを含む useFetch 関数を定義しました。
  • ハードコードされていた URL を削除し、カスタムフックに引数として渡せるように url バリアブル(変数)に置き換えました。
  • 最後に、フックから取得した data をリターン(返却)するようにしました。

main.jsx では、useFetch フックをインポートし、他の標準的な Hook と同様に利用しています。ここでデータを取得したい URL を渡しています。

これにより、このカスタムフックをどのコンポーネントでも再利用して、任意の URL からデータをフェッチできるようになりました。