Next.js跨路由跳转后如何访问GiftProvider中的gift状态
首先你需要先解决路由匹配不对应的问题:你当前跳转的路径是/gift/${gift.id}/personalize,但你现有pages目录下的personalize/index.tsx只能匹配根路径下的/personalize路由,二者无法匹配,需要先调整结构或者跳转路径,再解决状态传递的问题,以下是几个可行方案:
方案1:调整目录结构复用Provider(最推荐)
步骤1:调整pages目录结构,匹配跳转路由
/pages /gift /[slug] index.tsx /personalize index.tsx
步骤2:提取公共布局嵌套GiftProvider
在/pages/gift/[slug]目录下新建GiftSlugLayout.tsx公共布局组件,把GiftProvider放在这个布局里:
// /pages/gift/[slug]/GiftSlugLayout.tsx import { GiftProvider } from '你的GiftProvider路径' export default function GiftSlugLayout({ gift, children }) { return <GiftProvider gift={gift}>{children}</GiftProvider> }
步骤3:两个页面共用布局+SSG获取gift数据
/gift/[slug]/index.tsx和/gift/[slug]/personalize/index.tsx都用这个布局包裹,同时两个页面都通过getStaticProps根据路由参数slug查询对应的gift数据,和你原有的SSG逻辑保持一致即可,两个页面都可以通过useContext拿到GiftProvider里的gift状态。
方案2:路由参数传递轻量数据
如果gift数据量很小,不需要跨页面共享Provider,也可以在跳转时把需要的字段放到查询参数里:
const goToPersonalize = () => { router.push({ pathname: '/personalize', query: { slug: gift.id, giftName: gift.name, giftPrice: gift.price // 其他你需要的字段 } }) }
在personalize页面直接通过useRouter的query属性就能拿到对应字段。
方案3:本地存储/全局状态管理传递复杂数据
如果gift数据复杂且不想重复请求,可以在跳转前把数据存入本地存储或全局状态工具:
// 跳转前存储 const goToPersonalize = () => { localStorage.setItem('currentGift', JSON.stringify(gift)) router.push(`/gift/${gift.id}/personalize`) } // personalize页面初始化时读取 const currentGift = JSON.parse(localStorage.getItem('currentGift') || '{}') // 页面销毁时可以清空避免脏数据 useEffect(() => { return () => localStorage.removeItem('currentGift') }, [])
如果项目已经接入Zustand、Redux、Jotai等全局状态管理工具,也可以直接把gift存入全局状态,在personalize页面直接读取即可。
方案4:全局挂载GiftProvider
如果多页面都需要用到gift状态,可以直接把GiftProvider挂载到根_app.tsx中,全局所有页面都能直接访问gift状态,注意要在离开gift相关页面时清空gift状态,避免不同路由的数据串扰。
内容的提问来源于stack exchange,提问作者S.M_Emamian

