React 实现map渲染多按钮的点击选中背景色切换
批量渲染按钮的单选背景切换实现
实现核心思路
别给每个按钮单独存点击状态,就靠父组件已经维护的selectedCategory当唯一的选中判断标准:循环渲染时给每个按钮传上自己的唯一id,子组件拿到父组件的全局选中值后,和自己的id比一下,对得上就加高亮样式,对不上就用默认样式。这种写法天然能满足“点哪个哪个亮、点新的旧的暗回去”的要求,还不用写多余的状态清理逻辑。
具体修改步骤
1. 调整主组件传参
现有主组件已经实现了点击时更新selectedCategory状态的逻辑,只需要在循环渲染按钮时,把当前按钮对应的category.id作为prop传给子组件,供子组件做选中态比对即可,不需要新增冗余状态。
修改后的循环渲染代码:
const categoriesName = this.state.categories.map((category ,index) => { const visible_in_pricing_page = category.visible_in_pricing_page if (visible_in_pricing_page) { return <CategoryBtn index={index} name={category.title} key={category.id} // 传入当前按钮的唯一id,补充缺失的比对参数 btnId={category.id} selectedId={this.state.selectedCategory} clicked={() => this.categorySelectedHandler(category.id)} /> } });
补充说明:主组件state里的clicked1、value字段在当前场景没有实际作用,可直接删除减少冗余。
2. 修改按钮组件的类名拼接逻辑
原按钮组件固定使用默认类名,现在需要根据传入的btnId和selectedId的匹配结果,动态拼接对应的样式类。
修改后的CategoryBtn组件代码:
import React from 'react'; import classes from './price-category-btn.css'; const CategoryBtn = props => { // 判定当前按钮是否为选中态:自身id和全局选中id一致即为选中 const isSelected = props.btnId === props.selectedId; // 动态拼接类名:选中则追加高亮类,否则使用默认类 const finalClassName = isSelected ? `${classes.category_btn} ${classes.category_btn_active}` : classes.category_btn; return ( <div style={{display:"inline"}} > <a> <button className={finalClassName} onClick={props.clicked} > {props.name} </button> </a> </div> ) } export default CategoryBtn;
3. 补充选中态的样式规则
在对应的css文件price-category-btn.css中,新增选中态的样式类即可,比如:
/* 保留原有的默认按钮样式 */ .category_btn { /* 原有样式内容不变 */ } /* 新增选中态的背景色等样式 */ .category_btn_active { background-color: #自定义的高亮背景色值; /* 可根据需求补充文字颜色、边框、阴影等其他选中态样式 */ }
效果说明
- 因为全局只有一份
selectedCategory状态,同一时间最多只有一个按钮会匹配上选中判断条件,所以只会有一个按钮显示高亮背景,其余按钮保持默认样式 - 点击其他按钮时,父组件的
selectedCategory会自动更新为新点击按钮的id,之前高亮的按钮因为和新的选中值不匹配,会自动切回默认样式,不需要手动写逻辑清除之前的选中状态
内容的提问来源于stack exchange,提问作者user14866403
相关产品推荐
相关产品推荐

