React中点击某个tab时如何将其余所有数组对象的selected属性改为false
问题核心原因
- 你把选中状态
selected拆分到了每个子组件内部独立维护,子组件之间没有同步通道 - 直接修改原始数组属于数据突变,且该数组没有定义为父组件的响应式state,修改后React无法感知,不会触发组件重渲染,其余tab自然不会更新
- 子组件的
useState仅在首次挂载时用props赋值,后续props变化不会更新内部state,就算父组件数据改了子组件也不会响应
修复方案
把tab列表的状态提升到父组件统一管理,通过不可变的方式更新状态,再把最新状态向下传递给所有子组件即可。
import "./styles.css"; import React, { useState } from "react"; export default function App() { // 将tab列表定义为父组件的响应式state const [attributeValue, setAttributeValue] = useState([ { theValue: "theValue 1", selected: "false" }, { theValue: "theValue 2", selected: "false" }, { theValue: "theValue 3", selected: "false" }, { theValue: "theValue 4", selected: "false" }, { theValue: "theValue 5", selected: "false" } ]); // 父组件统一处理tab切换逻辑 const handleTabChange = (activeIndex) => { const newTabs = attributeValue.map((item, index) => ({ ...item, selected: index === activeIndex ? "true" : "false" })); setAttributeValue(newTabs); }; function TestingTabs({ theValue, theSelected, theIndex, onTabChange }) { return ( <div className={`customer__account__tabs ${ theSelected === "true" && "active_btn" }`} onClick={() => onTabChange(theIndex)} > <div className="customer__account__tabs__title">{theValue}</div> <div>{theSelected}</div> </div> ); } return ( <div> {attributeValue.map((obj, index) => { return ( <TestingTabs key={index} theValue={obj.theValue} theIndex={index} theSelected={obj.selected} onTabChange={handleTabChange} ></TestingTabs> ); })} </div> ); }
核心改动说明
- 将
attributeValue从普通变量改为父组件的useState管理的响应式状态 - 父组件统一封装切换逻辑,通过不可变的
map生成新数组更新状态,自动触发所有子组件重渲染 - 子组件不再维护独立的选中状态,直接消费父组件传递的
selected属性,点击时调用父组件传入的切换方法即可 - 补充了列表渲染必备的
key属性,避免React渲染异常
内容的提问来源于stack exchange,提问作者Aman Chaudhary
相关产品推荐
相关产品推荐

