React中使用useState实现数组单个元素独立控制开关状态问题
问题原因
你当前所有Switch组件共享同一个isActive状态变量,点击任意一个开关时,这个全局状态值会被修改,导致所有开关同步切换状态。
解决方案
将状态改为对象类型,单独存储每个开关的激活状态,而非单个布尔值。具体修改如下:
- 初始化状态为包含所有dashboard项的对象,每项默认值为
false:
const [activeStates, setActiveStates] = useState( dashboardItems.reduce((acc, item) => { acc[item] = false; return acc; }, {}) );
- 修改点击事件处理函数,接收当前点击的项作为参数,仅更新对应项的状态:
const handleClick = (item) => { setActiveStates(prev => ({ ...prev, [item]: !prev[item] })); };
- 渲染Switch时,根据当前项从
activeStates中获取对应状态:
<Switch onClick={() => handleClick(dashboardItem)} status={activeStates[dashboardItem] ? "active" : "inactive"} />
修改后的完整代码
const dashboardItems = ["news", "notifications", "letters"]; const Settings = (props) => { const { t } = useTranslation("settings"); const [activeStates, setActiveStates] = useState( dashboardItems.reduce((acc, item) => { acc[item] = false; return acc; }, {}) ); const handleClick = (item) => { setActiveStates(prev => ({ ...prev, [item]: !prev[item] })); }; return ( <SideMenu class="dashboard-settings"> <SideMenu.Item> <SideMenu.Header>{t("Dashboard Settings")}</SideMenu.Header> </SideMenu.Item> {dashboardItems.map((dashboardItem) => ( <SideMenu.Item key={dashboardItem}> {t(dashboardItem)}{" "} <Switch onClick={() => handleClick(dashboardItem)} status={activeStates[dashboardItem] ? "active" : "inactive"} /> </SideMenu.Item> ))} </SideMenu> ); };
补充说明
- 用
reduce初始化状态对象,可自动根据dashboardItems生成对应键值对,避免重复代码。 - 状态更新使用函数式更新(
prev => ...),确保每次更新基于最新状态值,避免异步更新导致的状态不一致。 - 每个Switch的点击事件绑定当前项,点击时仅修改对应项的状态,实现独立控制。
内容的提问来源于stack exchange,提问作者R-me
相关产品推荐
相关产品推荐

