開発トラブルシューティング
React State Management Troubleshooting
Reactの状態管理に関する一般的な問題と解決策
React State Management Troubleshooting
このドキュメントは、Reactの状態管理に関する一般的な問題と解決策を記録します。
問題1: propsの変更が内部stateに反映されない
症状
- 親コンポーネントからpropsとして渡されるデータが変更されても、子コンポーネントのUIが更新されない
- サーバーサイドやAPIレスポンスでは正しいデータが返されているが、画面に反映されない
- コンソールログでは正しい値が表示されるが、レンダリングされる内容は古いまま
根本原因
ReactのuseStateフックは、コンポーネントの初回レンダリング時のみ初期値を使用します。その後、propsが変更されても、内部stateは自動的には更新されません。
// ❌ 問題のあるコード
export const MyComponent = ({ initialData }) => {
const [data, setData] = useState(initialData);
// initialDataが変更されても、dataは更新されない
return <div>{data.map(item => ...)}</div>;
};解決策
方法1: useEffectで同期する(推奨)
propsの変更を検知して、内部stateを更新します。
// ✅ 解決策
export const MyComponent = ({ initialData }) => {
const [data, setData] = useState(initialData);
// propsが変更されたら内部stateを更新
useEffect(() => {
setData(initialData);
}, [initialData]);
return <div>{data.map(item => ...)}</div>;
};方法2: propsを直接使用する
内部で状態を変更する必要がない場合は、propsを直接使用します。
// ✅ より良い解決策(状態変更が不要な場合)
export const MyComponent = ({ data }) => {
// 内部stateを使わず、propsを直接使用
return <div>{data.map(item => ...)}</div>;
};方法3: keyプロパティでコンポーネントを再マウント
データが完全に変わる場合は、keyを使ってコンポーネントを再マウントします。
// ✅ 代替案(データが完全に変わる場合)
<MyComponent key={dataId} initialData={data} />実際の事例: Libraryページの検索フィルタリング
状況:
LibraryPageClientコンポーネントが、親からinitialItemsを受け取る- 検索やタグフィルタリングで親コンポーネントが再レンダリングされ、新しい
initialItemsが渡される - しかし、UIには反映されない
原因:
export const LibraryPageClient = ({ initialItems }) => {
const [items, setItems] = useState(initialItems);
// ↑ 初回のみinitialItemsを使用。その後の変更は無視される解決:
export const LibraryPageClient = ({ initialItems }) => {
const [items, setItems] = useState(initialItems);
// initialItemsが変更されたら内部stateを更新
useEffect(() => {
setItems(initialItems);
}, [initialItems]);関連する問題
Next.jsのサーバーコンポーネントとキャッシュ
Next.jsのサーバーコンポーネントはデフォルトでキャッシュされるため、検索パラメータが変わってもページが再レンダリングされない場合があります。
解決策:
// ページコンポーネントに追加
export const dynamic = 'force-dynamic';ベストプラクティス
-
propsを直接使用できないか検討する
- 内部で状態を変更する必要がない場合は、propsを直接使用する方がシンプル
-
useEffectの依存配列を正しく設定する
- 依存配列に必要な値をすべて含める
- ESLintの
react-hooks/exhaustive-depsルールに従う
-
パフォーマンスを考慮する
- propsが頻繁に変更される場合、
useMemoやuseCallbackを検討 - 不要な再レンダリングを避けるため、依存配列を最小限にする
- propsが頻繁に変更される場合、
-
デバッグ方法
useEffect内でコンソールログを出力して、いつ更新されるか確認- React DevToolsで props と state の変化を追跡
参考リンク
最終更新: 2025-11-27
関連タスク: feat-explore-phase7d (Explore/Library/MyWorksページのUI統一)