ReactのuseStateで検索フィルターや設定画面を実装する際、以下のようなカテゴリごとの選択肢をネストしたオブジェクトで管理することがあります。
{
"category1": { "option1": true, "option2": false },
"category2": { "option3": true }
}
この時、スプレッド演算子とオプショナルチェーンを組み合わせることで特定のオプションだけを安全に更新できます。
実装例
type NestedState = Record<string, Record<string, boolean>>
const [checkedItems, setCheckedItems] = useState<NestedState>({})
const handleOptionToggle = (categoryKey: string, option: string) => {
setCheckedItems((prev) => {
const newCheckedItems = {
...prev,
[categoryKey]: {
...prev[categoryKey],
[option]: !prev[categoryKey]?.[option],
},
}
// 必要に応じて選択済みオプションを抽出
const selectedOptions = Object.keys(newCheckedItems[categoryKey]).filter(
(key) => newCheckedItems[categoryKey][key],
)
return newCheckedItems
})
}
解説
スプレッド演算子でネストを展開
const newState = {
...prev, // 他のカテゴリを保持
[categoryKey]: {
...prev[categoryKey], // 他のオプションを保持
[option]: !prev[categoryKey]?.[option], // 対象のみトグル
},
}
外側のスプレッドで他のカテゴリを維持し、内側のスプレッドで同一カテゴリ内の他のオプションを維持
オプショナルチェーンで安全にアクセスできる
!prev[categoryKey]?.[option]
categoryKeyが存在しない場合、undefinedを返すだけでエラーにはなりません。