[React.js] - パート16: React Hooks - Reactのカスタムフック

Ace Lennox
Reactのカスタムフックは、複数のコンポーネント間でロジックを再利用するための強力な方法です。共通の機能を再利用可能な関数として抽出することで、コードを**DRY(Don't Repeat Yourself)**に保ち、メンテナンス性を向上させることができます。このガイドでは、カスタムフックの作成と使用方法を簡単な例を使って解説します。
カスタムフックとは?
カスタムフックは、Reactのロジックを再利用可能な関数としてカプセル化したものです。名前は必ずuse
から始まり(例:useFetch
)、状態やエフェクト、その他のフックロジックを含むことができます。
なぜカスタムフックを使うのか?
再利用性: 複数のコンポーネントでロジックを共有できます。
コードの簡潔さ: 複雑なロジックをコンポーネントから切り離し、可読性を向上させます。
一貫性: アプリ全体で共通のパターンを標準化できます。
例1: カスタムフックを使わないデータ取得
以下は、Home
コンポーネントでデータを取得して表示する例です。
index.js
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
const Home = () => {
const [data, setData] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((data) => setData(data));
}, []);
return (
<div>
<h2>投稿一覧</h2>
{data &&
data.map((post) => (
<p key={post.id}>{post.title}</p>
))}
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Home />);
問題点
別のコンポーネントでもデータを取得する必要がある場合、このロジックを繰り返す必要があります。これはDRY原則に反し、コードのメンテナンスが困難になります。
例2: カスタムフックの作成
取得ロジックをuseFetch
という名前の再利用可能なカスタムフックに抽出します。
useFetch.js
import { useState, useEffect } from "react";
const useFetch = (url) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setLoading(true);
try {
const response = await fetch(url);
const result = await response.json();
setData(result);
} catch (error) {
console.error("データ取得エラー:", error);
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading };
};
export default useFetch;
説明
再利用可能なロジック:
useFetch
はURLを引数に取り、データとローディング状態を返します。非同期処理:
async/await
で読みやすい非同期コードを実現します。エラーハンドリング: エラーが発生した場合も適切に処理します。
例3: カスタムフックの利用
Home
コンポーネントでuseFetch
を使用してデータを取得します。
index.js
import ReactDOM from "react-dom/client";
import useFetch from "./useFetch";
const Home = () => {
const { data, loading } = useFetch("https://jsonplaceholder.typicode.com/posts");
if (loading) {
return <h2>読み込み中...</h2>;
}
return (
<div>
<h2>投稿一覧</h2>
{data &&
data.map((post) => (
<p key={post.id}>{post.title}</p>
))}
</div>
);
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Home />);
改善点
シンプルなコンポーネント:
Home
コンポーネントはUIのレンダリングに集中できます。再利用可能なフック: 他のコンポーネントでも簡単にデータ取得ロジックを再利用できます。
スケーラビリティ: フックに機能を追加すると、すべての利用箇所に恩恵を与えます。
カスタムフックの利点
カプセル化: ロジックをUIから分離できます。
再利用性: 複数のコンポーネントで同じロジックを使えます。
スケーラビリティ: フックを拡張することでアプリ全体の機能が向上します。
ベストプラクティス
use
から始める: Reactの規約に従い、カスタムフック名はuse
で始めます。副作用を避ける: フック内では副作用を避け、純粋なロジックに集中します。
使いやすい設計: 引数や返り値をわかりやすく設計します。
エッジケースの処理: エラーやローディング状態を適切に処理します。
まとめ
Reactのカスタムフックは、ロジックを整理し、再利用可能でスケーラブルなコードを書くための重要なツールです。カスタムフックを作成することで、コンポーネントをシンプルに保ち、アプリケーション全体のメンテナンス性を向上させることができます。
この記事の例を参考に、ぜひ独自のカスタムフックを作成してみてください!
ソースコード
このプロジェクトの完全なソースコードはGitHubで利用可能です。