React中使用useRef修改点击表格行<tr>背景色的问题解决
实现行点击高亮的最优方案
你当前的思路是通过绑定在<table>上的ref查找DOM子元素、再直接修改DOM样式,这种命令式操作DOM的方式在React中不仅维护成本高,还很容易出现和组件渲染状态不同步的问题。结合你现有代码结构,最适合的实现方式是用组件状态驱动行的高亮样式,全程不需要手动操作DOM,也不需要用到绑定在表格上的ref。
具体改造步骤
- 引入
useStateHook,用来记录当前被选中的行索引(你现有代码里已经用行索引作为tr的id和key,刚好可以复用这个值作为行的唯一标识) - 修改行点击事件的处理逻辑:点击行时把当前行的索引更新到状态中,支持重复点击同一行取消选中
- 渲染
<tr>元素时,根据当前的选中状态动态判断是否给该行加高亮类名
改造后的完整代码
import React, { useState } from "react"; import "./TableBox.css"; const TableBox = ({ table_data }) => { // 新增状态:记录当前选中的行索引,初始无选中值 const [selectedRow, setSelectedRow] = useState(null); // 改造行点击事件:传入当前行的索引 const handlerRowClicked = (rowIndex) => { // 如果点击的是已经选中的行,就清空选中状态;否则更新为当前点击的行索引 setSelectedRow(prev => prev === rowIndex ? null : rowIndex) }; return ( <div> {/* 原来绑定在table上的myTable ref完全没用,可以删掉 */} <table> <thead> <tr> {Object.keys(table_data[0]).map((title) => ( <th key={title}>{title}</th> ))} </tr> </thead> <tbody> {table_data.map((row, index) => ( <tr key={index} // 动态给tr加类名:如果当前行是选中的行,就加row-highlight类 className={selectedRow === index ? "row-highlight" : ""} // 点击事件直接传入当前行的索引,不需要再从event里找元素 onClick={() => handlerRowClicked(index)} > {Object.keys(row).map((key) => ( <td key={row[key]}>{row[key]}</td> ))} </tr> ))} </tbody> </table> </div> ); }; export default TableBox;
配套样式(写在你的TableBox.css里即可)
.row-highlight { background-color: #e6f7ff; /* 这里可以换成你想要的高亮背景色 */ cursor: pointer; }
补充:如果你确实需要通过id操作DOM的实现逻辑(不推荐)
如果你坚持要通过DOM操作修改样式,也不需要借助绑在<table>上的ref找子元素:
- 点击行时,事件回调可以直接通过
event.currentTarget拿到被点击的<tr>原生DOM元素 - 因为你给每个
<tr>都绑定了id为行索引的值,可以通过全局DOM查找document.getElementById(行索引值)拿到对应行 - 但这种方式的弊端是:每次点击新行时,需要手动把之前所有带高亮样式的行的样式清除,一旦组件因为state变化重渲染,手动修改的DOM样式很容易被React的虚拟DOM更新冲掉,后续加多选、行编辑等功能时维护成本极高,不建议在React项目里使用。
内容的提问来源于stack exchange,提问作者afshin
相关产品推荐
相关产品推荐

