React/JS中统计页面打开时长?解决MUI Datagrid加载崩溃问题
解决方案:MUI Datagrid因API延迟导致弹窗崩溃问题
核心问题拆解
你当前的问题本质不是页面打开时长,而是数据未就绪时触发了依赖数据的组件渲染。getRowId需要基于行数据生成唯一ID,当API还未返回数据时,Datagrid拿到空值或undefined,直接调用getRowId就会引发崩溃。
最优解决方案:基于数据加载状态控制弹窗
与其判断页面时长,不如直接根据数据的加载状态处理,这才是从根源解决问题的思路:
管理数据加载状态
在组件中维护data和isLoading两个状态,API请求开始时设置isLoading = true,请求完成(成功/失败)后更新data并将isLoading设为false。点击按钮时的逻辑处理
- 用户点击打开弹窗按钮时,先检查
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
相关产品推荐
相关产品推荐

