
本文详解如何在 react 中实现“门店”与“商品”两级联动下拉框:当用户切换或清空门店时,自动清空已选商品并重新渲染对应商品列表,避免残留选项或无法重新选择的问题。
本文详解如何在 react 中实现“门店”与“商品”两级联动下拉框:当用户切换或清空门店时,自动清空已选商品并重新渲染对应商品列表,避免残留选项或无法重新选择的问题。
在 React 应用中构建级联下拉选择器(如先选门店、再选该门店下的商品)时,一个常见痛点是:清空上级筛选(如门店)后,下级下拉框未重置,导致仍显示旧选项、无法重新完整加载新数据,甚至出现已选值与当前可选项不匹配的情况。根本原因在于:下拉框的 value 状态未随上级筛选变化而同步重置,且选项列表未在依赖变更时强制刷新。
以下是一个健壮、可复用的解决方案,核心包含三点:
使用 @ainative/react-sdk 为 React 应用添加 AI 聊天和积分。适用于 (1) 安装 @ainative/react-sdk,(2) 使用 useChat hook 实现聊天完成。
✅ 状态解耦:为“门店”和“商品”分别维护独立状态;
✅ 依赖驱动渲染:商品下拉项完全由 selectedStore 实时计算生成,确保数据源始终最新;
✅ 自动重置:当 selectedStore 清空(如设为 '')时,商品下拉自动变为空列表,且已选值被清空,杜绝残留。
✅ 完整示例代码(TypeScript + 函数组件)
import { useState, useEffect } from 'react';
// 模拟门店数据
const stores = [
{ storeId: 101, storeName: 'Store X' },
{ storeId: 102, storeName: 'Store Y' },
{ storeId: 103, storeName: 'Store Z' },
];
// 模拟全量商品数据(含所属门店 ID)
const allItems = [
{ itemId: 1, storeId: 101, itemName: 'Store X - Product A' },
{ itemId: 2, storeId: 102, itemName: 'Store Y - Product B' },
{ itemId: 3, storeId: 103, itemName: 'Store Z - Product C' },
{ itemId: 4, storeId: 101, itemName: 'Store X - Product D' },
// ... 更多数据(略)
];
export default function StoreItemSelector() {
const [selectedStore, setSelectedStore] = useState<string>('');
const [selectedItem, setSelectedItem] = useState<string>('');
// ✅ 关键:当 selectedStore 改变时,自动清空 selectedItem
useEffect(() => {
setSelectedItem(''); // 防止旧值残留导致 UI 不一致
}, [selectedStore]);
// 动态过滤当前门店下的商品
const filteredItems = allItems.filter(
item => item.storeId.toString() === selectedStore
);
return (
<div classname="selector-group">
{/* 门店下拉框 */}
<label htmlfor="store">门店:</label>
<select id="store" value="{selectedStore}" onchange="{(e)"> setSelectedStore(e.target.value)}
>
<option value="">请选择门店</option>
{stores.map((store) => (
<option key="{store.storeId}" value="{store.storeId}">
{store.storeName}
</option>
))}
</select>
{/* 商品下拉框 —— 完全受 selectedStore 控制 */}
<label htmlfor="item" style="{{" margintop: display:>
商品:
</label>
<select id="item" value="{selectedItem}" onchange="{(e)"> setSelectedItem(e.target.value)}
disabled={!selectedStore} // 无门店时禁用,提升 UX
>
<option value="">请选择商品</option>
{filteredItems.map((item) => (
<option key="{item.itemId}" value="{item.itemId}">
{item.itemName}
</option>
))}
</select>
</div>
);
}</string></string>
⚠️ 关键注意事项
- 不要手动缓存过滤结果:避免使用类似 const items = useMemo(...) 但未正确设置依赖数组(如遗漏 selectedStore),否则会导致选项列表不更新;
- 务必重置子级状态:通过 useEffect 监听 selectedStore 变化并清空 selectedItem,否则可能出现「选项已消失但输入框仍显示旧值」的 UI 错误;
- 启用 disabled 属性:当 selectedStore 为空时禁用商品下拉框,既防止误操作,也明确传达依赖关系;
- key 值必须唯一且稳定:
- 若需支持多选或搜索增强,建议迁移到 react-select 等成熟库,但核心状态联动逻辑不变。
通过以上设计,用户每次切换门店时,商品下拉框将彻底刷新、自动清空已选项,并完整呈现该门店专属商品列表——无需刷新页面,体验流畅可控。










