Gatsby中Reach Router编程导航时组件不渲染问题
问题核心原因
你遇到的URL正常更新、但路由组件不渲染反而显示Gatsby静态路由列表,本质是Gatsby的两层路由机制没有对齐:
Gatsby是静态站点生成框架,第一优先级会用pages目录下的文件结构匹配URL,生成独立的静态路由页面。如果Gatsby的静态路由层找不到对应URL的匹配页面,开发环境下就会直接展示包含所有可访问路由列表的默认404页面,根本不会加载你写在某一个静态页面里的Reach Router组件。
你现在能看到带default属性的PageTest1正常渲染,是因为你当时访问的URL刚好能落到你写了<Router>组件的那个静态页面上,一旦编程式导航跳到其他路径,Gatsby静态层直接判定无匹配页面触发404,自然跑不通你的Router逻辑。
具体调整步骤
- 创建能覆盖所有客户端路由范围的Gatsby动态匹配页面
不要把<Router>直接写在/index.js这类固定静态页面组件里,需要在pages目录下创建通配符匹配的动态路由组件,承接所有你要走Reach Router的URL,避免被Gatsby静态层拦截触发404。
比如你要实现路径的客户端渲染,就根据你规划的路由前缀创建对应结构:要做全路径通配就创建pages/[...].js,匹配所有Gatsby静态层没命中的URL;要把客户端路由统一放在/app前缀下,就创建pages/app/[...].js,承接所有/app开头的URL请求。 - 显式给Reach Router传入Gatsby注入的
location属性
Gatsby会给所有页面组件自动注入路由相关的location对象,必须把这个属性显式传给Reach Router,不然会出现Router内部路径监听和Gatsby路由状态不同步的问题,示例代码:
注意Router内的// pages/app/[...].js 通配符动态匹配组件 import { Router } from "@reach/router" import PageTest1 from "../components/PageTest1" import PageTest2 from "../components/PageTest2" import PageTest3 from "../components/PageTest3" // 接收Gatsby自动注入的location props export default function ClientRouteContainer({ location }) { return ( <Router location={location}> <PageTest1 default /> <PageTest2 path="/test2"/> <PageTest3 path="/test3"/> </Router> ) }path是相对于当前通配符页面的挂载路径,比如pages/app/[...].js的匹配前缀是/app,Router里写的/test2实际对应完整URL就是/app/test2。 - 编程式导航统一使用Gatsby提供的
navigate方法
不要直接用Reach Router内置的navigate做跳转,要从Gatsby核心导入navigate方法,跳转时填写完整的目标URL(比如navigate("/app/test2")),保证Gatsby静态层能正确把请求导向你的通配符动态页面,不会触发404。
常见误区提示
开发环境下Gatsby展示的“静态路由列表”就是默认404页面的典型特征,只要调整通配符匹配范围,让目标URL能被Gatsby静态层正确导向你的Router组件,这个列表就不会再出现。
内容的提问来源于stack exchange,提问作者Abdel Matyne
相关产品推荐
相关产品推荐

