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

Next.js中router.query刷新为undefined、Link跳转正常如何解决?

问题原因

这是Next.js路由的固有特性,出现该问题的核心原因如下:

  • Next.js 客户端初始化、hydration 未完成时,useRouter()返回的router.query默认是空对象。只有路由完全初始化完成后,动态路由参数才会注入到query字段中。
  • 你通过<Link>组件跳转属于Next.js客户端侧路由接管,跳转时参数已经提前传递到目标页面,所以可以直接拿到值;而刷新页面是浏览器直接发起资源请求加载页面,需要等客户端hydration、路由初始化完成后才能拿到query参数,所以首次渲染阶段mediaId为空。

解决方案

方案1:通过router.isReady判断路由初始化状态(推荐,改造成本最低)

useRouter提供了isReady字段,专门用于标识路由是否完成初始化、query参数是否可用,你只需要调整现有useEffect的依赖和判断逻辑即可:

useEffect(() => {
  // 路由未就绪时直接终止逻辑
  if (!router.isReady || !mediaId) return;
  getPostImage();

  async function getPostImage() {
    try {
      const { data } = await API.graphql({
        query: postById,
        variables: {
          id: mediaId,
        },
      });
      setPost(data.postById.items[0]);
    } catch (err) {
      console.log("error getPostImage", err);
    }
  }
}, [router.isReady, mediaId]); // 新增router.isReady作为依赖

方案2:通过getServerSideProps在服务端获取参数(适合需要SSR的场景)

如果需要页面刷新时也能在服务端就拿到参数、避免客户端请求闪烁,可以在页面文件中新增getServerSideProps逻辑,直接把参数作为props传递给组件:

// 写在页面组件同级
export async function getServerSideProps(context) {
  const { mediaId, user } = context.params;
  // 也可以直接在服务端完成接口请求,把post数据一起返回
  return {
    props: {
      mediaId,
      user
    }
  }
}

// 组件内直接从props取参数即可
const MediaPage = ({mediaId, user}) => {
  // 原有逻辑,不需要再从router.query解构mediaId
}

方案3:SSG静态生成场景配置getStaticPaths

如果你的页面用的是SSG静态生成模式,需要补充getStaticPaths配置声明所有需要预渲染的动态路由路径,同时根据业务需求设置fallback为true/'blocking',即可保证静态页面也能正确拿到路由参数。

额外注意

你现有代码中直接判断if (user === null) return null,但user变量没有定义,需要补充从router.query解构user参数的逻辑,否则会触发未定义变量报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 20:36:06