
本文介绍如何使用 React 的 useState 和状态提升实现两个联动下拉框:选择颜色后,食物列表自动过滤为仅显示匹配该颜色的食物。
本文介绍如何使用 react 的 `usestate` 和状态提升实现两个联动下拉框:选择颜色后,食物列表自动过滤为仅显示匹配该颜色的食物。
在 React 应用中,组件间的数据联动依赖于状态(state)驱动的重新渲染,而非直接操作 DOM(如 document.getElementById())。你当前的 Dropdown 组件是无状态的、彼此隔离的,因此无法感知颜色选择的变化。解决方案是:将颜色选择状态提升至父组件(HomePage),再将其作为 prop 传递给食物下拉框,并在内部完成条件过滤。
以下是完整、可运行的实现步骤:
✅ 步骤 1:在 HomePage 中管理颜色状态
使用 useState 存储当前选中的颜色,并通过 onChange 事件实时更新:
// page.js
'use client';
import Dropdown from './data-import';
export default function HomePage() {
const [selectedColor, setSelectedColor] = useState('');
return (
<div>
<dropdown type="colors" value="{selectedColor}" onchange="{(e)"> setSelectedColor(e.target.value)}
/>
<dropdown type="food_types" selectedcolor="{selectedColor}"></dropdown></dropdown>
</div>
);
}
? 注意:value 和 onChange 是原生
✅ 步骤 2:增强 Dropdown 组件以支持受控模式与过滤逻辑
// data-import.js
'use client';
import foods from '../data/foods.json';
export default function Dropdown({ type, value, onChange, selectedColor }) {
let options = [];
if (type === 'colors') {
options = foods.colors.map((color) => (
<option key="{color}" value="{color}">
{color.charAt(0).toUpperCase() + color.slice(1)}
</option>
));
} else if (type === 'food_types') {
// 过滤:仅保留 color 字段匹配 selectedColor 的食物(若 selectedColor 为空,则显示全部)
const filteredFoods = selectedColor
? Object.entries(foods.food_types).filter(
([_, food]) => food.color === selectedColor
)
: Object.entries(foods.food_types);
options = filteredFoods.map(([name, _]) => (
<option key="{name}" value="{name}">
{name.charAt(0).toUpperCase() + name.slice(1)}
</option>
));
}
return (
<select value="{value" onchange="{onChange}" disabled type="=="><option value="">— Select a {type === 'colors' ? 'color' : 'food'} —</option>
{options}
</select>
);
}
✅ 关键要点说明:
- 状态提升(Lifting State Up):父组件统一管理共享状态(selectedColor),子组件只负责展示和触发变更。
- 受控组件原则:
- 过滤逻辑放在渲染时:每次 selectedColor 变化,组件重渲染 → filteredFoods 重新计算 → 下拉选项自动更新。
- 空值处理:添加默认提示选项(— Select a ... —),并合理处理 selectedColor 为空时的全量展示逻辑。
- 大小写优化:使用 charAt(0).toUpperCase() 提升用户体验(如显示 “Apple” 而非 “apple”)。
⚠️ 常见错误规避:
- ❌ 不要使用 document.getElementById() 或 window.onload —— 这违背 React 的声明式数据流,且在服务端渲染(SSR)中会报错。
- ❌ 不要在 Dropdown 内部用 useState 管理颜色(会导致两个下拉框状态不一致)。
- ❌ 避免在 map 中直接修改 foods.food_types 对象(它是只读 JSON);始终基于原始数据做不可变过滤。
通过以上改造,你的应用即可实现“选颜色 → 刷食物”的流畅交互,完全符合 React 的最佳实践。











