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

React useEffect处理大数据表格:平滑过渡的最佳实践

React 17.0.2 大数据表格渲染最佳实践

针对大数据表格渲染卡顿的问题,场景二中的延迟加载只是临时缓解方案,更彻底的优化可以从以下几个方向入手:

1. 开启虚拟滚动(最核心的优化)

Material React Table内置了虚拟滚动支持,开启后只会渲染当前可视区域内的行,直接减少DOM节点数量,从根源解决卡顿问题。

const [tableData, setTableData] = useState([]);

useEffect(() => {
  setTableData([...largeData]);
}, []);

return (
  <MaterialReactTable
    columns={columnsList}
    data={tableData}
    enableVirtualization // 启用虚拟滚动
    virtualizerProps={{
      overscan: 5, // 预渲染可视区域上下各5行,提升滚动流畅度
    }}
  />
);

2. 渐进式数据加载(分批渲染)

不要一次性加载所有数据,而是分批次逐步追加,让浏览器有时间处理UI渲染:

const [tableData, setTableData] = useState([]);
const batchSize = 100; // 每次加载100条

useEffect(() => {
  let currentIndex = 0;
  const totalData = [...largeData];

  const loadBatch = () => {
    const endIndex = Math.min(currentIndex + batchSize, totalData.length);
    setTableData(prev => [...prev, ...totalData.slice(currentIndex, endIndex)]);
    currentIndex = endIndex;

    if (currentIndex < totalData.length) {
      // 利用requestIdleCallback在浏览器空闲时加载下一批
      requestIdleCallback(loadBatch);
    }
  };

  loadBatch();

  return () => {
    currentIndex = totalData.length; // 清理时终止后续加载
  };
}, []);

return (
  <MaterialReactTable
    columns={columnsList}
    data={tableData}
  />
);

3. 避免不必要的重渲染

  • 用React.memo包裹表格组件,确保只有data或columns变化时才重渲染;
  • 用useMemo缓存columns和经过处理的数据,避免每次渲染都重新生成:
const memoizedColumns = useMemo(() => columnsList, []);
const processedData = useMemo(() => {
  // 如果需要对大数据做格式化等处理,这里用useMemo缓存结果
  return [...largeData];
}, []);

const [tableData, setTableData] = useState([]);

useEffect(() => {
  setTableData(processedData);
}, [processedData]);

return (
  <MaterialReactTable
    columns={memoizedColumns}
    data={tableData}
  />
);

4. 异步处理大数据计算

如果需要对大数据做复杂处理(比如过滤、排序、格式化),把这些逻辑放到Web Worker中,避免阻塞主线程:

// 主线程代码
const [tableData, setTableData] = useState([]);

useEffect(() => {
  const worker = new Worker('./dataProcessor.js');
  worker.postMessage(largeData);
  worker.onmessage = (e) => {
    setTableData(e.data);
    worker.terminate();
  };

  return () => worker.terminate();
}, []);

// dataProcessor.js(Web Worker文件)
self.onmessage = (e) => {
  const processedData = e.data.map(item => {
    // 这里做复杂的数据处理逻辑
    return { ...item, formattedDate: new Date(item.date).toLocaleString() };
  });
  self.postMessage(processedData);
};

5. 优化延迟加载方案(替代固定超时)

如果暂时无法实现上述方案,用requestIdleCallback替代setTimeout,让数据加载在浏览器空闲时执行,比固定延迟更合理:

const [tableData, setTableData] = useState([]);

useEffect(() => {
  let idleCallbackId;
  
  const loadData = () => {
    setTableData(stateTable.recentSmsDataRed);
  };

  idleCallbackId = requestIdleCallback(loadData);

  return () => {
    cancelIdleCallback(idleCallbackId);
  };
}, [stateTable.recentSmsDataRed]);

return (
  <MaterialReactTable
    columns={columnsList}
    data={tableData}
  />
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 00:52:16