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

Gatsby中使用useLocation钩子获取URL参数时服务端渲染(SSR)报错问题求助

问题原因与解决方案

为什么会出现这个问题?

Gatsby 采用**服务端渲染(SSR)**和静态站点生成(SSG)的混合模式,在构建或服务端渲染阶段,代码是运行在 Node.js 环境中的——这时候没有浏览器的 window 对象,也无法获取当前浏览器的 URL 上下文。

你用 useLocation().search 拿到的结果,在浏览器端是包含 ?page=7 的字符串,但在 Node.js 环境里是空字符串或 undefined。当你执行 split('=')[1] 时,空字符串拆分后只会得到一个元素的数组,取索引 [1] 就会返回 undefined,转成 Number 自然就是 NaN。

而 Gatsby 要求 React 组件在浏览器和 Node.js 环境中必须渲染出一致的内容,这种两端不一致的结果(浏览器是数字,SSR 是 NaN)就触发了报错。


解决方案

这里有几种可靠的解决方式,你可以根据自己的场景选择:

1. 用 useEffect 延迟获取参数(最通用)

useEffect 钩子只会在浏览器端执行,SSR 阶段不会运行,这样就能避免 Node 环境下的异常:

import { useLocation } from '@reach/router';
import { useState, useEffect } from 'react';

const JobOffersPage = () => {
  const [pageParam, setPageParam] = useState(1); // 设置默认页码
  const location = useLocation();

  useEffect(() => {
    // 用 URLSearchParams 解析查询参数,比手动 split 更健壮
    const searchParams = new URLSearchParams(location.search);
    const pageValue = searchParams.get('page');
    // 校验参数有效性,避免非数字值
    setPageParam(pageValue && !isNaN(Number(pageValue)) ? Number(pageValue) : 1);
  }, [location.search]);

  return <div>当前页码:{pageParam}</div>;
};

export default JobOffersPage;

2. 直接判断浏览器环境

通过 typeof window !== 'undefined' 区分环境,在 SSR 时使用默认值,浏览器端再解析参数:

import { useLocation } from '@reach/router';

const JobOffersPage = () => {
  const location = useLocation();
  // 默认页码设为1,保证SSR时的渲染一致性
  let pageParam = 1;

  if (typeof window !== 'undefined') {
    const searchParams = new URLSearchParams(location.search);
    const pageValue = searchParams.get('page');
    pageParam = pageValue && !isNaN(Number(pageValue)) ? Number(pageValue) : 1;
  }

  return <div>当前页码:{pageParam}</div>;
};

export default JobOffersPage;

3. 用 getServerData 获取服务端请求参数(Gatsby v4+)

如果你的页面是服务端渲染模式(比如使用 Gatsby Cloud 或自托管 SSR),可以在页面组件中导出 getServerData,直接从服务端请求中获取查询参数:

// 仅适用于 Gatsby v4 及以上的页面组件
export async function getServerData({ request }) {
  const url = new URL(request.url);
  const pageValue = url.searchParams.get('page');
  const pageParam = pageValue && !isNaN(Number(pageValue)) ? Number(pageValue) : 1;

  return {
    props: { pageParam },
  };
}

const JobOffersPage = ({ pageParam }) => {
  return <div>当前页码:{pageParam}</div>;
};

export default JobOffersPage;

额外提醒

尽量避免手动用 split 解析 URL 查询参数,因为如果参数顺序变化、存在多个参数或者参数值包含特殊字符,这种方式很容易出错。URLSearchParams 是浏览器原生的 API,能更安全可靠地处理查询参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 23:32:40