Next.js中useRouter.query值无法渲染页面,如何等待router.isReady?
解决Next.js路由Query值未渲染到HTML的问题
问题根源:你用普通let变量存储communityName和threadName,但useEffect是组件初始渲染完成后才执行的,而且普通变量的变化不会触发组件重渲染。所以初始渲染时变量未赋值,页面显示空值,后续赋值后也不会更新页面。
下面是几种可行的解决方法:
方法1:用React状态管理变量
把普通变量换成useState,在router.isReady时更新状态,状态变化会触发组件重渲染,从而显示正确的值:
import { useRouter } from 'next/router'; import React, { useState, useEffect } from 'react'; const Thread = () => { const router = useRouter(); const [communityName, setCommunityName] = useState(''); const [threadName, setThreadName] = useState(''); useEffect(() => { if (router.isReady) { const name = router.query['community-name']?.replaceAll('-', ' ') || ''; setCommunityName(name); const thread = router.query['thread-name']?.replaceAll('-', ' ') || ''; setThreadName(thread); } }, [router.isReady]); // 未准备好时可以显示加载提示 if (!router.isReady) { return <div>加载中...</div>; } return ( <h1> Hello from the {communityName} Forum!<br /><br /> You're receiving the thread named {threadName}! </h1> ); }; export default Thread;
方法2:使用getServerSideProps(仅Pages Router)
如果你的页面是服务端渲染场景,可以直接在服务器端获取query参数,传给组件,这样组件初始化就有值,不需要等待客户端路由就绪:
import React from 'react'; const Thread = ({ communityName, threadName }) => { return ( <h1> Hello from the {communityName} Forum!<br /><br /> You're receiving the thread named {threadName}! </h1> ); }; export async function getServerSideProps(context) { const { query } = context; const communityName = query['community-name']?.replaceAll('-', ' ') || ''; const threadName = query['thread-name']?.replaceAll('-', ' ') || ''; return { props: { communityName, threadName }, }; } export default Thread;
方法3:直接在渲染逻辑中判断router.isReady
不需要额外状态,直接在渲染时等待router.isReady,就绪后再处理query:
import { useRouter } from 'next/router'; import React from 'react'; const Thread = () => { const router = useRouter(); if (!router.isReady) { return <div>加载中...</div>; } const communityName = router.query['community-name']?.replaceAll('-', ' ') || ''; const threadName = router.query['thread-name']?.replaceAll('-', ' ') || ''; return ( <h1> Hello from the {communityName} Forum!<br /><br /> You're receiving the thread named {threadName}! </h1> ); }; export default Thread;
内容的提问来源于stack exchange,提问作者cfrost
相关产品推荐
相关产品推荐

