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

React/JS中统计页面打开时长?解决MUI Datagrid加载崩溃问题

解决方案:MUI Datagrid因API延迟导致弹窗崩溃问题

核心问题拆解

你当前的问题本质不是页面打开时长,而是数据未就绪时触发了依赖数据的组件渲染。getRowId需要基于行数据生成唯一ID,当API还未返回数据时,Datagrid拿到空值或undefined,直接调用getRowId就会引发崩溃。

最优解决方案:基于数据加载状态控制弹窗

与其判断页面时长,不如直接根据数据的加载状态处理,这才是从根源解决问题的思路:

  1. 管理数据加载状态
    在组件中维护data和isLoading两个状态,API请求开始时设置isLoading = true,请求完成(成功/失败)后更新data并将isLoading设为false。

  2. 点击按钮时的逻辑处理

  • 用户点击打开弹窗按钮时,先检查data是否就绪:
    • 若data已加载完成:直接打开弹窗渲染Datagrid。
    • 若data未就绪:可以将按钮置灰并显示“数据加载中”提示,或者自动等待API请求完成后再打开弹窗。

代码示例(React Hooks):

import { useState, useEffect } from 'react';
import { Button, Dialog, DialogContent } from '@mui/material';
import { DataGrid } from '@mui/x-data-grid';

const YourComponent = () => {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [modalOpen, setModalOpen] = useState(false);

  // 模拟API请求
  useEffect(() => {
    const fetchTableData = async () => {
      try {
        const res = await fetch('your-api-endpoint');
        const result = await res.json();
        setData(result);
      } catch (err) {
        console.error('数据加载失败:', err);
      } finally {
        setIsLoading(false);
      }
    };
    fetchTableData();
  }, []);

  const handleOpenModal = () => {
    if (isLoading) {
      // 数据未加载完时的提示,也可以改成自动等待加载完成后打开弹窗
      alert('数据正在加载,请稍候');
      return;
    }
    setModalOpen(true);
  };

  return (
    <>
      <Button 
        onClick={handleOpenModal}
        disabled={isLoading}
        variant="contained"
      >
        {isLoading ? '数据加载中...' : '打开表格弹窗'}
      </Button>
      <Dialog open={modalOpen} onClose={() => setModalOpen(false)}>
        <DialogContent>
          {isLoading ? (
            <div>加载中...</div>
          ) : (
            <DataGrid
              rows={data}
              columns={yourColumnConfig}
              getRowId={(row) => row.id} // 此时数据已就绪,不会崩溃
            />
          )}
        </DialogContent>
      </Dialog>
    </>
  );
};

export default YourComponent;

若坚持使用页面时长判断方案

如果一定要基于页面打开时长做延迟,可以在组件挂载时记录时间戳,点击按钮时计算时间差:

const YourComponent = () => {
  const [mountTimestamp, setMountTimestamp] = useState(Date.now());
  const [modalOpen, setModalOpen] = useState(false);

  useEffect(() => {
    setMountTimestamp(Date.now());
  }, []);

  const handleOpenModal = () => {
    const elapsed = Date.now() - mountTimestamp;
    const threshold = 2000; // 2秒阈值

    if (elapsed < threshold) {
      setTimeout(() => setModalOpen(true), threshold - elapsed);
    } else {
      setModalOpen(true);
    }
  };

  // 其他组件逻辑...
};

注意:这个方案是绕开本质问题的妥协方案,如果API加载时间超过阈值,依然会导致崩溃,不推荐使用。

额外优化:给Datagrid加容错处理

还可以直接在Datagrid层面做容错,确保即使数据未加载完成也不会崩溃:

<DataGrid
  rows={data || []} // 确保rows始终是数组类型
  columns={yourColumnConfig}
  getRowId={(row) => row?.id || `temp-${Math.random()}`} // 生成临时ID避免崩溃
  loading={isLoading} // 利用Datagrid自带的加载状态
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:06:20