Next.js刷新带动态ID页面出现未处理运行时错误排查
问题原因及解决方案
核心问题拆解
你遇到的报错本质是页面刷新时,data 处于未就绪(加载中/加载失败)状态,或者请求本身因为路由 id 未正确获取而失败,导致直接访问 data.image 时触发空值读取错误。具体几个关键点:
1. 路由id初始为空,导致请求无效
Next.js 的 useRouter 在页面刷新时,router.query.id 不会立刻有值(SSR/SSG场景下更明显),这时候你发起的请求是 /api/user/undefined,接口返回错误后,你的 fetchGetUserInformation 函数在 catch 里只打印错误但没重新抛出异常,React-Query 会把 data 设为 undefined,后续访问 data.image 就会报错。
2. React-Query 查询键未关联id
你的查询键是固定的 ['userData'],当 id 变化(包括刷新后 id 从无到有)时,React-Query 不会自动重新触发查询,导致始终用错误的 id 请求数据,data 一直是错误状态。
3. 未处理加载/错误状态
代码里直接渲染 data.image,完全没考虑 isLoading(数据还在加载)和 isError(请求失败)的情况,这两种场景下 data 都是空值,必然触发报错。
具体修复步骤
第一步:修复路由id的获取与请求触发逻辑
先判断 id 是否存在,不存在时不要发起请求:
const router = useRouter(); const { id } = router.query; // 只有当id存在时才允许发起请求 const fetchGetUserInformation = async () => { if (!id) throw new Error('User ID is missing'); try { const response = await fetch(`/api/user/${id}`, { method: 'GET', }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { // 重新抛出错误,让React-Query捕获并标记isError throw error; } };
第二步:把id加入React-Query的查询键
这样当id变化时,React-Query会自动重新发起查询:
const { isLoading, isError, data, error } = useQuery( ['userData', id], // 加入id作为查询键的一部分 fetchGetUserInformation, { // 只有id存在时才执行查询 enabled: !!id, } );
第三步:渲染时处理加载、错误状态
在获取到有效data之前,不要直接访问data.image:
if (isLoading) return <div>加载中...</div>; if (isError) return <div>加载失败:{error.message}</div>; // 确保data存在后再渲染 if (!data) return <div>无用户数据</div>; return ( <div className='mt-3'> <img className='w-36 h-36 rounded ml-2' src={data.image} alt='Profile image' /> </div> );
内容的提问来源于stack exchange,提问作者Amrod92
相关产品推荐
相关产品推荐

