[英]NextJS: How can I use a loading component instead of nprogress?
Is it possible to use a <Loading />
component in NextJS instead of nprogress?是否可以在 NextJS 中使用
<Loading />
组件而不是 nprogress? I'm thinking you would need to access some high level props like pageProps
from the router events so you can toggle the loading state and then conditionally output a loading component but I don't see a way to do this...我认为您需要从路由器事件中访问一些高级道具,例如
pageProps
,以便您可以切换加载状态,然后有条件地输出加载组件,但我没有看到这样做的方法...
For example,例如,
Router.events.on("routeChangeStart", (url, pageProps) => {
pageProps.loading = true;
});
and in the render并在渲染中
const { Component, pageProps } = this.props;
return pageProps.loading ? <Loading /> : <Page />;
But of course, routeChangeStart
doesn't pass in pageProps.但是当然,
routeChangeStart
不会传入 pageProps。
Yes, it is possible to use another component to handle loading instead of nProgress.是的,可以使用另一个组件而不是 nProgress 来处理加载。 I had a similar question, and found the solution below working out for me.
我有一个类似的问题,并找到了适合我的解决方案。
It makes sense to do all this in ./pages/_app.js
, because according to the documentation that can help with persisting layout and state between pages.在
./pages/_app.js
完成所有这些是./pages/_app.js
,因为根据可以帮助在页面之间保持布局和状态的文档。 You can initiate the Router events on the lifecycle method componentDidMount
.您可以在生命周期方法
componentDidMount
上启动 Router 事件。 It's important to note that _app.js
only mounts once, but initiating Router events will still work here.需要注意的是
_app.js
只挂载一次,但启动 Router 事件在这里仍然有效。 This will allow you to be able to set state.这将使您能够设置状态。
Below is an example of how this all comes together:以下是所有这些如何结合在一起的示例:
import React, { Fragment } from 'react';
import App from 'next/app';
import Head from 'next/head';
import Router from 'next/router';
class MyApp extends App {
state = { isLoading: false }
componentDidMount() {
// Logging to prove _app.js only mounts once,
// but initializing router events here will also accomplishes
// goal of setting state on route change
console.log('MOUNT');
Router.events.on('routeChangeStart', () => {
this.setState({ isLoading: true });
});
Router.events.on('routeChangeComplete', () => {
this.setState({ isLoading: false });
});
Router.events.on('routeChangeError', () => {
this.setState({ isLoading: false });
});
}
render() {
const { Component, pageProps } = this.props;
const { isLoading } = this.state;
return (
<Fragment>
<Head>
<title>My App</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
</Head>
{/* You could also pass isLoading state to Component and handle logic there */}
<Component {...pageProps} />
{isLoading && 'STRING OR LOADING COMPONENT HERE...'}
</Fragment>
);
}
}
MyApp.getInitialProps = async ({ Component, ctx }) => {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
return { pageProps };
};
export default MyApp;
Use the hook below to inspect router's loading status:使用下面的钩子检查路由器的加载状态:
import Router from 'next/router'
import { useState, useEffect } from 'react'
const useRouterLoading = () => {
const [loading, setLoading] = useState(false)
useEffect(() => {
const start = () => setLoading(true)
const end = () => 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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.