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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 21:41:10