React点击元素切换CSS类名修改样式的实现与报错排查

问题根因
你的代码存在3个直接导致报错、效果不生效的问题:
- 控制台抛出
Uncaught TypeError: Cannot set properties of null (setting 'onclick')的原因:你在组件里写了原生DOM操作逻辑(类似document.getElementById('xxx').onclick = xxx的代码),React还没把对应DOM渲染到页面时你就去获取节点,拿到的是null,自然无法绑定事件。把所有原生JS获取DOM、绑事件、手动改类名的逻辑全删掉,React是状态驱动视图的框架,不需要这类操作。 - 样式不生效的原因:CSS里定义的高亮类名是
.selected,但你JSX里判断状态后追加的类名写的是selector,单词拼写错误,样式规则根本匹配不到元素。 - 逻辑扩展性问题:你用布尔值控制样式,只能支持单个列表项的固定状态切换,没法实现“点击任意项、仅当前点击项高亮”的互斥效果,多列表项场景下需要存当前选中项的唯一标识做判断。
可直接运行的正确实现
React 代码
import { useState } from 'react'; // 列表数据统一抽离,后续新增项直接改数组即可 const electrodeList = [ { id: 1, name: 'Magnesium' }, { id: 2, name: 'Zinc' }, { id: 3, name: 'Iron' }, { id: 4, name: 'Copper' } ]; export default function ElectrodeSelector() { // 存储当前选中项的id,初始值为null代表默认无选中项,要默认选第一项就填1 const [activeItemId, setActiveItemId] = useState(null); return ( <div> <ul className='editElectrodeBox'> {electrodeList.map(item => ( <li key={item.id} // 当前项id和激活id匹配时,追加selected高亮类 className={`electrodeBoxItem ${activeItemId === item.id ? 'selected' : ''}`} // 点击时把当前项id设为激活值 onClick={() => setActiveItemId(item.id)} > {item.name} </li> ))} </ul> </div> ); }
CSS 代码
你的原有CSS样式规则没有问题,修正类名匹配后即可正常生效:
.editElectrodeBox { height: 35vh; list-style: none; overflow-y: scroll; background-image: linear-gradient(to left, rgb(162, 234, 142) , rgb(118, 203, 240)); } .electrodeBoxItem { padding: 20px; cursor: pointer; } .selected { background-image: linear-gradient(135deg, #f34079 40%, #fc894d); color: whitesmoke; }
开发注意点
- 写React时不要沿用原生JS先拿DOM再改属性的开发思路,所有视图变化都通过修改state触发,React会自动帮你更新DOM,从根源上避免DOM获取不到的问题。
- 类名、变量名写完做基础检查,拼写错误属于排查成本很高的低级问题。
- 同类型的列表元素优先用数组遍历渲染,比逐个手写标签更好维护,状态逻辑也更统一。
内容的提问来源于stack exchange,提问作者SebR
相关产品推荐
相关产品推荐

