問題
リファクタリング前のコードは、1つのコンポーネントに多くの責任が集中していました。
この記事では、カスタムフックを使って状態管理を分離し、コードの可読性と再利用性を向上させる方法を紹介します。
リファクタリング前
PracticePage.tsx
// PracticePage.tsx(リファクタリング前)
const PracticePage = () => {
const [words, setWords] = useState<Word[]>([]);
const [error, setError] = useState<string | null>(null);
// 他にも多くの状態...
useEffect(() => {
const fetchWordsByTag = async () => {
// 50行以上の複雑なロジック...
};
fetchWordsByTag();
}, [selectedTagId, user, tagList]);
// その他のロジックも多数...
return (
// JSXも複雑...
);
};
解決方法
カスタムフックを作成することで、状態管理ロジックを独立させることができます。
リファクタリング後
useWordsByTag.ts
// カスタムフック作成
// filepath: /src/hooks/useWordsByTag.ts
import { useState, useEffect } from 'react';
// ...既存のimport...
export const useWordsByTag = (
selectedTagId: string,
user: User | null,
tagList: Tag[]
) => {
const [words, setWords] = useState<Word[]>([]);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchWordsByTag = async () => {
// データ取得ロジック...
};
fetchWordsByTag();
}, [selectedTagId, user, tagList]);
return { words, error, setWords };
};
PracticePage.tsx
const PracticePage = () => {
// 省略
// 関数呼び出しで状態管理できる
const { words, error: wordsError, setWords } = useWordsByTag(
selectedTagId,
user,
tagList
);
// コンポーネントはUIロジックに集中
return (
// 省略
);
};
終わりに
今回のリファクタリングで、カスタムフックを使った状態管理の分離という新しい手法を学べました。
AIと対話しながらリファクタリングを進めることで、自分だけでは思いつかない実装パターンを知ることができました
- 状態管理ロジックを別ファイルの関数(カスタムフック)で管理できる
-
useEffect
による状態監視も含めて、まるごと切り出せる - コンポーネントは関数を呼び出すだけで複雑な状態管理が使える