我的项目中有多个getServerSideProps
,我有一个显示页面的标题,一旦我点击它,我必须等待页面打开,因为我需要获取数据。获取它们后,页面将打开。
我用来向用户显示加载状态的一种方法是使用,routeChangeStart
但我偶然发现了一个问题,所以我不想使用这种情况。
如果我进入一个页面并且正在获取数据,我想向用户显示一个微调器或一些指示器,并且一旦获取了数据,我想停止指示器/微调器。
我的项目中有多个getServerSideProps
,我有一个显示页面的标题,一旦我点击它,我必须等待页面打开,因为我需要获取数据。获取它们后,页面将打开。
我用来向用户显示加载状态的一种方法是使用,routeChangeStart
但我偶然发现了一个问题,所以我不想使用这种情况。
如果我进入一个页面并且正在获取数据,我想向用户显示一个微调器或一些指示器,并且一旦获取了数据,我想停止指示器/微调器。
我刚用过routeChangeStart
。
我不想使用它,因为 router.push('/map') 在 pages/index.tsx 文件中不起作用,但我通过创建一个新组件将 router.push 置于使用效果并渲染加载程序来解决此问题。
routeChangeStart
在 _app.js 中,因此在 index.js router.push() 中不起作用-我对其进行了测试
routeChangeStart - 它是如何工作的?
当我们点击一个页面时,数据正在服务器上获取,并且只有在获取数据后页面才会显示给我们。所以我们可以做下一件事,我们可以拦截路由变化。
当我们点击一个链接(我们等待数据获取)时,我们将加载状态设置routeChangeStart
为true
,如果我们移动到另一个页面(这意味着我们获取了数据),我们调用routeChangeComplete
一旦我们移动到我们想要的路线就会运行,并且这里我们将加载状态设置为 false。在此之后我只是通过加载状态使用React Context
正如您可能已经知道的那样,getServerSideProps
它在服务器上运行并处于阻塞状态。获取请求需要在 HTML 发送给用户之前完成(即页面被更改)。因此,如果要显示加载指示器,则需要将该获取请求移至客户端。
例如,如果您可能有一个具有这种基本结构的页面:
export default function Page({ data }) {
return <div>{data.name}</div>
}
export async function getServerSideProps() {
const response = await fetch('https://example.com/api')
const data = await response.json()
return {
props: { data },
}
}
const fetcher = url => fetch(url).then(res => res.json());
export default function Page() {
const { data } = useSWR('https://example.com/api', fetcher)
if (!data) return <LoadingSpinner />
return <div>{data.name}</div>
}
或者,如果您不需要 SWR 并且可以使用简单的 fetch 请求:
export default function Page() {
const [data, setData] = useState()
useEffect(() => {
fetch('https://example.com/api')
.then(async(response) => {
const json = await response.json()
setData(json)
})
})
if (!data) return <LoadingSpinner />
return <div>{data.name}</div>
}
PS 如果初始获取请求中getServerSideProps
使用了敏感信息(例如,API 机密凭据),则继续设置Next.js API 路由来处理敏感部分,然后获取新路由。