Next.js useRouter/withRouter在第一次渲染中查询时接收未定义
我的动态路线有问题。看起来像这样Next.js useRouter/withRouter在第一次渲染中查询时接收未定义,next.js,Next.js,我的动态路线有问题。看起来像这样 [lang]/abc 我试图从[lang]中获取查询值,但当我使用useRouter/withRouter时,我在页面的2-3次呈现期间得到了查询(第一次得到query.lang=undefined)。它可以在1渲染或使用任何技术 无法在第一次渲染时获取查询值 静态优化的页面没有提供路由参数。例如,query是一个空对象({}) 水合后,Next.js将填充查询对象 Next.js 10.0.5及更高版本 使用router.isReadyinsideuseffe
[lang]/abc
我试图从[lang]
中获取查询值,但当我使用useRouter/withRouter
时,我在页面的2-3次呈现期间得到了查询(第一次得到query.lang=undefined
)。它可以在1渲染或使用任何技术
无法在第一次渲染时获取查询值 静态优化的页面没有提供路由参数。例如,
query
是一个空对象({}
)
水合后,Next.js将填充查询对象
Next.js 10.0.5及更高版本
使用router.isReady
insideuseffect
hook检查参数是否准备就绪。有关示例,请参见@dy063给出的答案
在Next.js 10.0.5之前
第一次渲染动态路由时,router.asPath
和router.route
是相等的。一旦query
对象可用,router.asPath
就会反映它
更改asPath
后,您可以依赖useffect
钩子中的查询值
const router = useRouter();
useEffect(() => {
if (router.asPath !== router.route) {
// router.query.lang is defined
}
}, [router])
我解决了我的问题,我需要在Hoc组件中使用它。 我使用withRouter(withLocale(Comp))包装并在HOC中创建条件
export default function withLocale(WrappedPage) {
const WithLocale = ({ router, ...props }) => {
const { lang } = router.query;
if (!lang || !isLocale(lang)) {
return <Error statusCode={404} />;
}
return (
<LocaleProvider lang={lang}>
<WrappedPage {...props} />
</LocaleProvider>
);
};
return WithLocale;
}
使用Locale导出默认函数(WrappedPage){
const with locale=({router,…props})=>{
const{lang}=router.query;
如果(!lang | |!isLocale(lang)){
返回;
}
返回(
);
};
用locale返回;
}
在NextJS 9中,确保页面组件可以立即使用路由参数的一种方法是从传递到getServerSideProps()
的上下文中获取路由参数,并作为道具传递到组件
对于像[id].js这样的页面
导出函数getServerSideProps(上下文){
返回{
道具:{params:context.params}
};
}
导出默认值({params})=>{
const{id}=params;
返回您用{id}打开的页面;
};
这是一部好作品,我从
添加useQuery.ts
helper文件
//useQuery.js
从“下一个/路由器”导入{useRouter};
//解析查询或返回null
导出默认函数useQuery(){
const router=useRouter();
常量HaskeryParams=
/\[.+\]/.test(router.route)|/\?./.test(router.asPath);
const ready=!hasQueryParams | | Object.keys(router.query).length>0;
如果(!ready)返回null;
返回router.query;
}
用法
//在组件中(而不是useRouter)
const query=useQuery();
useffect(()=>{
如果(!查询){
返回;
}
log('my query exists!!',query);
},[查询];
我发现了一些东西:
isReady:布尔值-路由器字段是否已在客户端更新并准备好使用。应仅在useEffect方法内部使用,而不是在服务器上有条件地呈现。
代码如下:
const router=useRouter();
useffect(()=>{
如果(!router.isReady)返回;
//使用router.query的代码
},[router.isReady]);
在下一个9.4.4上尝试了这个,我得到了一个错误,因为context.props
是未定义的
,无法序列化为JSON。希望它会包含查询。是的,这不起作用。context.props
context没有props
,请看下面的示例。您的页面道具将从getServerSideProps
接收您返回的{props:{}}
。您好@Mycolaos,答案实际上是利用上下文。参数
-而不是上下文。道具
。只是在接下来的10分钟里重新确认了方法。参考:使用getServerSideProps
指示Next.js在每个请求的服务器端预呈现页面。意味着它不是静态优化和缓存的。只有当你想牺牲表现时才使用它。例如,如果您必须在第一次渲染之前获取数据。tnx很多:))您应该小心使用这种方法,因为它有缺陷,因为asPath
和route
可以相等,这并不反映路由器的实际准备情况。只有当你的URL总是有一个查询时,你才能相信这一点。这应该是公认的答案。这正是isReady推出的目的。与其他可能产生奇怪副作用的棘手解决方案相比,它就像一个魅力!谢谢