Reactアプリケーションのアーキテクチャの一例として公開されているGitHubリポジトリ「bulletproof-react」が大変勉強になるのでシェアします。
1. 集中的なステート管理
アプリケーションの状態管理は、最も重要な設計上の決定の1つです。
ベストプラクティス
-
グローバルステート:React QueryやZustandを使用
// グローバルステートの例(Zustand) const useStore = create((set) => ({ user: null, setUser: (user) => set({ user }), logout: () => set({ user: null }) }));
-
ローカルステート:useStateやuseReducerを活用
// ローカルステートの例 const [isOpen, setIsOpen] = useState(false);
キーポイント
- 状態管理はシンプルに保つ
- 必要な場所でのみステートを使用
- 適切なライブラリの選択
2. フィーチャーベースのファイル構成
プロジェクトの構造は、開発効率とコードの保守性に直接影響します。
推奨されるディレクトリ構造
src/
├── features/
│ ├── users/
│ │ ├── api/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── types/
│ │ └── utils/
│ └── products/
│ ├── api/
│ ├── components/
│ ├── hooks/
│ ├── types/
│ └── utils/
└── common/
├── components/
├── hooks/
└── utils/
メリット
- 機能単位での開発が容易
- コードの見つけやすさが向上
- スケーラビリティの確保
3. 明確なデータフロー
データの流れを明確にすることで、バグの発見と修正が容易になります。
実装例
// APIレイヤーの抽象化
export const userAPI = {
getUser: async (id: string) => {
const response = await axios.get(`/api/users/${id}`);
return response.data;
}
};
// React Queryの使用
export const useUser = (id: string) => {
return useQuery(['user', id], () => userAPI.getUser(id));
};
重要な要素
- データフェッチングの一元化
- エラーハンドリングの標準化
- ローディング状態の適切な管理
4. コンポーネントの分割
適切なコンポーネント分割は、コードの再利用性と保守性を高めます。
コンポーネント設計の例
// Presentational Component
const UserCard = ({ name, email }: UserCardProps) => (
<div className="card">
<h3>{name}</h3>
<p>{email}</p>
</div>
);
// Container Component
const UserCardContainer = ({ userId }: { userId: string }) => {
const { data, isLoading } = useUser(userId);
if (isLoading) return <Spinner />;
return <UserCard name={data.name} email={data.email} />;
};
ポイント
- ロジックと表示の分離
- 再利用可能なコンポーネント設計
- 明確なプロップスインターフェース
5. 一貫性のある設計パターン
プロジェクト全体で一貫したパターンを使用することで、開発効率が向上します。
実装例
// エラーバウンダリ
class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <ErrorMessage />;
}
return this.props.children;
}
}
// フォーム実装
const UserForm = () => {
const { register, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} />
<button type="submit">送信</button>
</form>
);
};
重要なポイント
- エラー処理の標準化
- フォーム実装の一貫性
- UIコンポーネントの統一
まとめ
Bulletproof Reactの5つの原則は、モダンなReactアプリケーション開発の基礎となります。これらの原則を適切に適用することで:
- メンテナンス性の高いコードベース
- 開発効率の向上
- バグの少ないアプリケーション
- チーム開発の円滑化
を実現できます。
ただし、これらの原則は絶対的なものではなく、プロジェクトの要件や規模に応じて柔軟に適用することが重要です。