React类组件中实现待办事项列表点击高亮功能的方法
解决React类组件中Todo项的高亮问题
嘿,刚学React的时候很容易想着直接操作DOM,这太正常了!但其实React的核心是数据驱动视图,咱们换个思路就能优雅搞定这个问题~
核心思路
不用直接去修改DOM元素的className,而是通过组件的state来记录当前选中项的索引,然后在渲染环节根据这个状态动态设置目标元素的类名——让React帮我们处理视图更新的事儿!
修改步骤拆解
- 初始化选中状态:在
state里新增selected字段,初始值设为-1(表示一开始没有任何项被选中)。 - 简化
selectItem方法:只需要更新state里的selected为当前点击项的索引,剩下的交给React的渲染机制处理就行。 - 动态渲染类名:在
map循环渲染每个Todo项时,判断当前项的索引是否等于state.selected,从而决定给高亮元素加active还是hidden类。
修改后的完整代码
export class Todo extends Component { constructor(props) { super(props); // 1. 初始化选中状态 this.state = {input: '', todos: this.getOldTodo(), selected: -1}; this.selectItem = this.selectItem.bind(this); this.deleteItem = this.deleteItem.bind(this); // 别忘绑定deleteItem方法 } // 你原来的其他方法(比如getOldTodo、deleteItem等)保持不变... // 2. 简化selectItem方法,只负责更新状态 selectItem(i) { // 可选逻辑:点击已选中的项时取消高亮,若不需要可直接写this.setState({selected: i}) this.setState(prevState => ({ selected: prevState.selected === i ? -1 : i })); } render() { return ( <div> <ul> {this.state.todos.map((todo, i) => { // 3. 动态判断当前项是否被选中 const isSelected = this.state.selected === i; return ( <li key={todo.key} className="todo-li-item" onClick={() => this.selectItem(i)}> <span className="todo-item">{todo.text}</span> <span onClick={(e) => { e.stopPropagation(); // 阻止点击删除按钮时触发父元素的高亮事件 this.deleteItem(i); }} className="delet-todo">✕</span> {/* 根据选中状态动态设置类名 */} <div id="todo-select" className={isSelected ? "active" : "hidden"}> <span id="todo-select-top"></span> <span id="todo-select-left"></span> </div> </li> ); })} </ul> </div> ); } }
额外小提示
- 我给
deleteItem的点击事件加了e.stopPropagation(),这样点击删除按钮时不会触发父元素的高亮逻辑,避免误操作。 selectItem里用了函数式更新setState(prevState => ...),这是因为新状态依赖于旧状态,这种写法能避免状态更新的异步问题,更安全。
这样修改后,完全遵循了React的设计模式,不用手动操作DOM,状态变化会自动触发视图更新,代码也更易维护~
内容的提问来源于stack exchange,提问作者Draxy
相关产品推荐
相关产品推荐

