You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ant Design V5.18 Table鼠标hover触发冗余渲染问题求助

解决Table悬停操作按钮导致的冗余渲染问题

你的问题核心是每次hover状态变化时,整个Table组件及所有行都会触发重渲染,根源在于:

  • columns和data每次组件渲染都会重新创建新对象,导致Table判定props发生变化
  • onRow返回的事件函数每次都是新实例,同样会触发Table重渲染
  • 操作列的render依赖hoveredRowKey,状态变化时会让所有行的操作列重新计算

优化方案:通过缓存减少不必要的重渲染

直接上修改后的代码,关键优化点已标注:

import { useState, useMemo, useCallback } from 'react';
import { Table, Button } from 'antd';

const YourTableComponent = () => {
  const [hoveredRowKey, setHoveredRowKey] = useState(null);

  // 1. 用useMemo缓存静态数据,避免每次渲染创建新数组
  const data = useMemo(() => [
    { key: '1', name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park' },
    { key: '2', name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park' },
    { key: '3', name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park' },
  ], []);

  // 2. 用useMemo缓存columns,仅当hoveredRowKey变化时才重新生成
  const columns = useMemo(() => [
    {
      title: 'Name',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: 'Age',
      dataIndex: 'age',
      key: 'age',
    },
    {
      title: 'Address',
      dataIndex: 'address',
      key: 'address',
    },
    {
      title: 'Action',
      key: 'action',
      render: (_, record) => (
        hoveredRowKey === record.key ? (
          <span>
            <Button type="link">Edit</Button>
            <Button type="link">Delete</Button>
          </span>
        ) : null
      ),
    },
  ], [hoveredRowKey]);

  // 3. 用useCallback缓存onRow的事件函数,避免每次渲染创建新函数
  const rowEvents = useCallback((record) => ({
    onMouseEnter: () => setHoveredRowKey(record.key),
    onMouseLeave: () => setHoveredRowKey(null),
  }), []);

  return (
    <Table
      dataSource={data}
      columns={columns}
      onRow={rowEvents}
    />
  );
};

export default YourTableComponent;

进阶优化:让操作列仅渲染当前hover行的按钮

如果上述优化后仍有轻微卡顿,可以把操作按钮拆成独立组件并用memo包裹,确保只有当前hover的行才会重新渲染操作按钮:

import { memo } from 'react';

// 独立的操作按钮组件,用memo包裹减少重渲染
const ActionButtons = memo(({ visible }) => {
  if (!visible) return null;
  return (
    <span>
      <Button type="link">Edit</Button>
      <Button type="link">Delete</Button>
    </span>
  );
});

// 在columns的render中替换为该组件
render: (_, record) => (
  <ActionButtons visible={hoveredRowKey === record.key} />
)

这样只有visible属性变化的行才会更新操作按钮,其他行的操作列不会触发重渲染。

内容的提问来源于stack exchange,提问作者Lisan Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:52:17