Next.js路由[...slug]点击Link跳转URL更新但内容不刷新问题
问题根因
你遇到的跳转后内容不更新的核心原因是组件复用后状态未同步更新:
- 你封装的
useStoryblok钩子中,内部story状态仅在组件首次挂载时用传入的originalStory(也就是页面props的page)初始化,当路由跳转、同个[...slug].js组件被复用时,新的pageprops传入不会触发内部状态更新,所以始终展示第一次渲染的内容。 - 另外你当前
NextLink的写法属于Next.js早期版本的旧写法,已经不推荐使用,也存在参数匹配错误的隐患。
解决步骤
步骤1:修复useStoryblok钩子的状态同步逻辑
在storyblok.js的useStoryblok函数中添加对originalStory的监听,当props传入的原始内容变化时同步更新内部状态:
export function useStoryblok(originalStory, preview) { let [story, setStory] = useState(originalStory); // 新增这段useEffect,监听originalStory变化同步更新状态 useEffect(() => { setStory(originalStory) }, [originalStory]) // 剩下的原有逻辑保持不变... }
同时建议把initEventListeners函数用useCallback包裹,避免useEffect不必要的重复触发:
const initEventListeners = useCallback(() => { // 原有initEventListeners的逻辑不变 }, [story])
然后把原有useEffect的依赖项换成这个被useCallback包裹的函数即可。
步骤2:简化NextLink的写法
Next.js 9.5+之后已经支持直接给动态路由传实际路径,不需要再分开写href和as参数,直接修改为:
<NextLink href="/holidays/cruising"> Destinations test </NextLink>
框架会自动匹配到顶层的[...slug].js路由,不需要额外配置。
可选兜底方案
如果还是存在更新问题,可以给[...slug].js返回的根节点加上和路径绑定的key,强制路由变化时重新挂载组件:
const Slug = ({ page, preview, params }) => { let story = useStoryblok(page, preview); const pageKey = params.slug ? params.slug.join('-') : 'home' return ( <ThemeProvider key={pageKey}> {/* 原有内容不变 */} </ThemeProvider> ); };
你提到的新建holidays/[slug].js的方案是没必要的,顶层[...slug].js完全可以承载所有层级的路由需求,不需要拆分路由文件。
内容的提问来源于stack exchange,提问作者Acolos
相关产品推荐
相关产品推荐

