React中如何通过className实现单个按钮的颜色切换?
问题原因
你当前用单个布尔值状态toggle控制所有按钮的样式,所有按钮都基于同一个toggle值判断是否添加dark类,所以只要toggle反转,所有按钮会同步变色。
解决方案(单选模式:仅一个按钮保持深色)
这种模式适合分类筛选场景,每次只有一个选中的按钮:
- 修改状态定义:将
toggle改为记录当前选中按钮的id,初始值设为null(或默认选中的id,比如11对应"All") - 更新切换逻辑:点击按钮时,判断当前按钮是否已选中,是则取消选中(设为
null),否则记录该按钮的id - 调整className判断:每个按钮根据自身
id是否等于状态中的选中id来决定是否添加dark类
修改后的完整代码:
import './Clothing.css' import data from '../../data/data2.json'; import { useState } from 'react'; // 别忘了导入useState! const Clothing = () => { // 用id记录选中的按钮,初始为null表示无选中 const [selectedId, setSelectedId] = useState(null); const types = [ { id: 11, value: 'All' }, { id: 22, value: 'Cap' }, { id: 33, value: 'Sweatshirt' }, { id: 44, value: 'Hoodie' }, { id: 55, value: 'Shirt' } ] const handleToggle = (buttonId) => { // 点击已选中的按钮则取消,否则设置为当前按钮id setSelectedId(prevId => prevId === buttonId ? null : buttonId); } // 保留你的分类处理逻辑 const handleSelectedCategory = (e) => { // 你的分类处理代码... } return ( <div className="clothSection"> <div className="topMenu"> <div className="buttonDiv"> {types.map((t) => ( <button key={t.id} id={t.id} value={t.value} // 判断当前按钮id是否等于选中id,是则添加dark类 className={selectedId === t.id ? "dark" : null} onClick={(e) => { handleSelectedCategory(e); // 直接传入当前按钮的id,避免依赖e.target可能的问题 handleToggle(t.id); }} > {t.value} </button> ))} </div> </div> </div> ) } export default Clothing;
可选:多选模式(每个按钮独立切换)
如果需要每个按钮都能独立切换深色/默认样式,状态需要记录每个按钮的切换状态:
- 状态改为对象:键是按钮id,值是布尔值表示是否选中
- 更新切换逻辑:点击时反转对应id的状态
- 调整className判断:根据对象中对应id的布尔值决定是否加类
示例代码片段:
const Clothing = () => { // 初始化所有按钮状态为false(未选中) const [toggleStates, setToggleStates] = useState(() => types.reduce((acc, t) => ({...acc, [t.id]: false}), {}) ); const handleToggle = (buttonId) => { setToggleStates(prev => ({ ...prev, [buttonId]: !prev[buttonId] })); } // ...其他代码不变 return ( // ... <button className={toggleStates[t.id] ? "dark" : null} onClick={(e) => { handleSelectedCategory(e); handleToggle(t.id); }} > {t.value} </button> // ... ) }
额外注意点
- 必须导入
useState,原代码遗漏会导致报错 - 避免直接依赖
e.target.id,如果按钮内部有嵌套元素,e.target可能不是按钮本身,直接传入t.id更可靠 - 你的CSS代码逻辑正常,
.dark类会正确覆盖默认按钮样式
内容的提问来源于stack exchange,提问作者Crystal
相关产品推荐
相关产品推荐

