React实现点击切换Div样式:仅保留单个选中状态的问题
问题分析
你当前的代码里,每个SearchFilterAttributeBadge组件都独自维护了selectedSize状态,导致多个组件的选中状态互相独立,没法实现“仅选中一个”的效果。要解决这个问题,需要把选中状态提升到父组件,让所有子组件共享同一个状态源。
解决方案
1. 改造父组件
把选中状态和状态更新逻辑移到父组件中,统一管理所有子组件的选中状态:
import { useState } from 'react'; import SearchFilterAttributeBadge from './SearchFilterAttributeBadge'; export default function FilterParent() { // 父组件维护全局选中的ID const [selectedSizeId, setSelectedSizeId] = useState<string>(""); // 统一的选中状态更新函数 const handleSelectSize = (id: string) => { setSelectedSizeId(id); }; // 假设这是你的属性列表数据 const sizeAttributes = [/* 你的SearchFilterAtttribute类型数据 */]; return ( <div className="row"> {sizeAttributes.map(attr => ( <SearchFilterAttributeBadge key={attr.id} attribute={attr} category="size" clickHandler={(e) => { // 这里写你的原有点击逻辑,比如提交筛选参数 console.log('筛选参数:', e.currentTarget.dataset); }} selectedId={selectedSizeId} onSelect={handleSelectSize} /> ))} </div> ); }
2. 修改子组件
移除子组件自身的状态,改用父组件传递过来的状态和方法:
export default function SearchFilterAttributeBadge(props: { attribute: SearchFilterAtttribute; category: string; clickHandler: (event: React.MouseEvent<HTMLAnchorElement>) => void; selectedId: string; onSelect: (id: string) => void; }) { const currentAttrId = props.attribute.id.toString(); return ( <div className="col"> <a className={`badge size-badge ${props.selectedId === currentAttrId ? "selected-size" : ""}`} data-id={currentAttrId} data-name={props.category} data-value={props.attribute.name} onClick={(e) => { props.clickHandler(e); props.onSelect(currentAttrId); }} > {props.attribute.name} </a> </div> ); }
原理说明
通过状态提升,让所有子组件共用父组件的selectedSizeId状态:
- 点击任意子组件时,都会调用父组件的
handleSelectSize更新全局选中ID - 所有子组件都会根据父组件传递的
selectedId判断自己是否应该高亮,自然就实现了“单选”效果
内容的提问来源于stack exchange,提问作者PixelPaul
相关产品推荐
相关产品推荐

