antd表格行hover效果性能处理

故事发生在2025/4/7,简单阐述一下故事背景吧,我们需要实现一个hover隔行的效果。当我们hover在任意一行的时候,与当前hover的这一行每相隔n行也需要有高亮的样式。

技术栈

在本次需求开发中,是react、antd pro、scss这三个核心技术

之前的写法

用到了两个状态 第一个状态:hoverSpace(决定隔多少行显示下个高亮),第二个状态:hoverRowIndex(当前鼠标所处的行的索引)

先介绍一下公司前面的人实现这个需求的思路吧,首先给每表格的每一行绑定两个事件,分别是onMouseEnter、onMouseLeave这两个,当鼠标移入表格行的时候,将当前行所处的索引记录下来,当移出当前行的时候将当前行所引设置为null,然后根据这两个变量计算出哪些行需要高亮,然后动态设置高亮类名。

代码展示

因为项目源代码较长,所以这里就只展示关键代码了,主要看思路

tsx 复制代码
// table.tsx
import { ProTable } from "@ant-design/pro-components";

const Table = () => {
  const [hoverSpace, setHoverSpace] = useState(0);
  const [hoverRowIndex, setHoverRowIndex] = useState<number | null>(null);

  return (
    <ProTable
      rowClassName={(_, index) => {
        if (hoverSpace && hoverRowIndex !== null) {
          return (index - hoverRowIndex) % (hoverSpace + 1) === 0
            ? "ant-table-cell-row-hover"
            : "";
        }
      }}
      onRow={(_, index) => ({
        onMouseEnter: () => {
          setHoverRowIndex(index);
        },
        onMouseLeave: () => {
          setHoverRowIndex(null);
        },
      })}
    />
  );
};

export default Table;

卡顿原因分析

因为这个组件所挂载的dom比较多,所以这个页面渲染所需要的时间就比较长,而在react中当组件的props,或者组件中的状态更新了,那么这个组件就会重新渲染一次,当然,还有很多其他的原因也会导致组件重新渲染,这里就不一一列举了。而在这个案例中,当我们的鼠标不断在表格行中上下移动,导致hoverRowIndex这个状态频繁更新,进而导致组件频繁渲染。最终导致页面卡顿。

解决方案选择

根据上面已经分析出了原因,那么就针对这个问题进行优化解决。第一个方案:让组件渲染不要那么频繁,或者让组件的部分渲染,而不是整个重新渲染。第二个方案:不用第二个状态,用纯css完成,这个组件就不用重新渲染了。一开始就想用第一种方案,但是想了很久没想到一个比较好的解决方式,于是决定用第二种方式。

解决方式思路

在最开始的时候想到的是用:nth-child()这个伪类去实现,但是好像没不能满足hover时才出现的效果,后面想要兄弟选择器去选择(但是这个选择器只能选中当前这个元素后面的元素)

实现代码

ts 复制代码
//table.tsx

import { ProTable } from "@ant-design/pro-components";
import styles from "./index.module.scss";
const Table = () => {
  const [hoverSpace, setHoverSpace] = useState(0);

  return (
    <ProTable
      className={styles["table-container"]}
      rowClassName={(_, index) => {
        if (hoverSpace === 0) {
          return "";
        }
        return styles[`row-id-row-${index % (Number(hoverSpace) + 1)}`];
      }}
    />
  );
};

export default Table;
scss 复制代码
// index.module.scss

.table-container {
  @for $i from 0 through 11 {
    .row-id-row-#{$i}:hover,
    .row-id-row-#{$i}:hover ~ .row-id-row-#{$i} {
      td {
        background-color: #afdbfd !important;
      }
    }
  }
}

到这里本篇文章就结束啦,如果本文有哪些错误,还请各位大佬指正,有什么更好的实现方法也欢迎大佬们分享出来,供我这个小菜鸡学习学习,非常感谢......

相关推荐
Live0000026 分钟前
在鸿蒙中使用 Repeat 渲染嵌套列表,修改内层列表的一个元素,页面不会更新
前端·javascript·react native
柳杉27 分钟前
使用Ai从零开发智慧水利态势感知大屏(开源)
前端·javascript·数据可视化
兆子龙37 分钟前
从高阶函数到 Hooks:React 如何减轻开发者的心智负担(含 Demo + ahooks 推荐)
前端
狗胜42 分钟前
测试文章 - API抓取
前端
三小河42 分钟前
VS Code 集成 claude-code 教程:告别海外限制,无缝对接国内大模型
前端·程序员
jerrywus1 小时前
前端老哥的救命稻草:用 Obsidian 搞定 Claude Code 的「金鱼记忆」
前端·agent·claude
球球pick小樱花1 小时前
游戏官网前端工具库:海内外案例解析
前端·javascript·css
用户60572374873081 小时前
AI 编码助手的规范驱动开发 - OpenSpec 初探
前端·后端·程序员
狗胜1 小时前
AI观察日记 2026-03-02|CLAUDE、TYPE、APPFUNCTIONS:掘金热门里的下一步信号
前端