nextjs getServerSideProps 显示加载
Posted
技术标签:
【中文标题】nextjs getServerSideProps 显示加载【英文标题】:nextjs getServerSideProps show loading 【发布时间】:2020-06-30 11:28:39 【问题描述】:我在pages/post/index.js 中使用getServerSideProps:
import React from "react";
import Layout from "../../components/Layout";
function Post( post )
console.log("in render", post);
return (
<Layout title=post.name>
<pre>JSON.stringify(post, undefined, 2)</pre>
</Layout>
);
export async function getServerSideProps( query )
return fetch(
`$process.env.API_URL/api/post?id=$query.id`
)
.then(result => result.json())
.then(post => ( props: post ));
export default Post;
当我直接加载 /post/2
时,它按预期工作,但是当我通过单击链接从 /posts
转到 /post/2
时:
<Link
as=`/post/$post.id`
href=`/post?id=$post.id`
>
在 2 秒 (the api delay) 内似乎没有任何反应,然后显示内容。我可以在网络选项卡中看到_next/data/development/post/9.json
正在由fetchNextData 加载。
当我使用 next/Link
从一条路线移动到另一条路线时,我想显示一个加载微调器,但我在 getServerSideProps 上找不到任何允许我这样做的文档。
当我直接转到/post/:id
时,我希望在服务器端获取数据并获得一个完全呈现的页面(有效),但是当我移动到另一条路线时,应该从客户端获取数据(有效) .然而;我想要一个加载指示器,并且在数据请求期间不让 UI 冻结。
【问题讨论】:
【参考方案1】:您可以在_app.js
中使用nprogress
import NProgress from 'nprogress';
import "nprogress/nprogress.css";
import Router from 'next/router';
NProgress.configure(
minimum: 0.3,
easing: 'ease',
speed: 800,
showSpinner: false,
);
Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());
或动态导入到_app.js
以减小包大小
ProgessBar.js
import Router from 'next/router';
import NProgress from 'nprogress';
NProgress.configure(
minimum: 0.3,
easing: 'ease',
speed: 500,
showSpinner: false,
);
Router.events.on('routeChangeStart', () => NProgress.start());
Router.events.on('routeChangeComplete', () => NProgress.done());
Router.events.on('routeChangeError', () => NProgress.done());
export default function ()
return null;
_app.js
import "nprogress/nprogress.css";
import dynamic from 'next/dynamic';
const ProgressBar = dynamic(() => import('components/atoms/ProgressBar'), s-s-r: false );
const App = () =>
...
return <>
...
<ProgressBar />
</>
【讨论】:
谢谢,我会试试this example。 我最终选择了using hooks 不要忘记导入css,否则它不会显示。import "nprogress/nprogress.css";
【参考方案2】:
**Here is how I did it in NextJs with Material UI and nprogress**
import '../styles/globals.css';
import useEffect, useState from 'react';
import Router from 'next/router';
import NProgress from 'nprogress';
import useStyles from '../src/utils';
import CircularProgress from '@material-ui/core';
NProgress.configure( showSpinner: false );
function MyApp(
Component,
pageProps
)
const classes = useStyles();
const [loading, setLoading] = useState(false);
useEffect(() =>
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) jssStyles.parentElement.removeChild(jssStyles);
const start = () =>
console.log('start');
NProgress.start();
setLoading(true);
;
const end = () =>
console.log('findished');
NProgress.done();
setLoading(false);
;
Router.events.on('routeChangeStart', start);
Router.events.on('routeChangeComplete', end);
Router.events.on('routeChangeError', end);
return () =>
Router.events.off('routeChangeStart', start);
Router.events.off('routeChangeComplete', end);
Router.events.off('routeChangeError', end);
;
, []);
return (
<>
loading ? (
<div className=classes.centered>
<CircularProgress size=25 color='primary' />
</div>
) : (
<Component ...pageProps />
)
</>
);
export default MyApp;
结果:
【讨论】:
【参考方案3】:这是一个使用钩子的example。
pages/_app.js
import Router from "next/router";
export default function App( Component, pageProps )
const [loading, setLoading] = React.useState(false);
React.useEffect(() =>
const start = () =>
console.log("start");
setLoading(true);
;
const end = () =>
console.log("findished");
setLoading(false);
;
Router.events.on("routeChangeStart", start);
Router.events.on("routeChangeComplete", end);
Router.events.on("routeChangeError", end);
return () =>
Router.events.off("routeChangeStart", start);
Router.events.off("routeChangeComplete", end);
Router.events.off("routeChangeError", end);
;
, []);
return (
<>
loading ? (
<h1>Loading...</h1>
) : (
<Component ...pageProps />
)
</>
);
【讨论】:
感谢您提供出色的解决方案 它是否适用于使用getServerSideProps
的 s-s-r?它对我不起作用。
@ka8725 是的,它适用于 getServerSideProps以上是关于nextjs getServerSideProps 显示加载的主要内容,如果未能解决你的问题,请参考以下文章
为啥 NextJS 中的 ApolloGraphQL 示例使用 getStaticProps 而不是 getServerSideProps
在 NEXTJS 的 getServerSideProps() 中获取一些 html 表单数据(或对象)
如何将道具从组件传递到 NextJS 中的 getServerSideProps()?
nextjs getServerSideProps 显示加载