乐闻世界logo
搜索文章和话题

How to add transition loading when load page on nextjs?

2个答案

1
2

In Next.js, adding loading indicators during page transitions can be achieved through several methods. The following steps and examples illustrate how to implement this feature:

Using Route Event Listeners

Next.js's Router object provides route events that trigger functions when navigation begins and ends. We can leverage these events to show and hide the loading indicator.

jsx
import { useState, useEffect } from 'react'; import Router from 'next/router'; import NProgress from 'nprogress'; // This is a lightweight progress bar library // Here's how to use it within the component: function MyApp({ Component, pageProps }) { const [loading, setLoading] = useState(false); useEffect(() => { const handleStart = () => setLoading(true); // Set loading state when navigation starts const handleComplete = () => setLoading(false); // Clear loading state when navigation completes Router.events.on('routeChangeStart', handleStart); Router.events.on('routeChangeComplete', handleComplete); Router.events.on('routeChangeError', handleComplete); // Clear loading state if navigation errors return () => { Router.events.off('routeChangeStart', handleStart); Router.events.off('routeChangeComplete', handleComplete); Router.events.off('routeChangeError', handleComplete); }; }, []); return ( <div> {loading && ( <div className="loader">Loading...</div> // Customize the loader style here )} <Component {...pageProps} /> </div> ); }

Using the nprogress library provides a more professional and smooth loading indicator. It displays a thin progress bar at the top of the page. When using it, you need to include the nprogress CSS file, typically in your styles.css file or within the App component.

jsx
// In _app.js or another global component: import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; // This is the default CSS for nprogress import Router from 'next/router'; NProgress.configure({ showSpinner: false }); // You can choose to disable the spinner Router.events.on('routeChangeStart', () => NProgress.start()); Router.events.on('routeChangeComplete', () => NProgress.done()); Router.events.on('routeChangeError', () => NProgress.done());

Using a Custom App Component

A custom App component can add a global loading state during route changes. The principle is similar to using route event listeners, but it simplifies state management and prop passing.

jsx
import App from 'next/app'; import NProgress from 'nprogress'; import Router from 'next/router'; class MyApp extends App { constructor(props) { super(props); this.state = { loading: false }; Router.events.on('routeChangeStart', () => { this.setState({ loading: true }); NProgress.start(); }); Router.events.on('routeChangeComplete', () => { this.setState({ loading: false }); NProgress.done(); }); Router.events.on('routeChangeError', () => { this.setState({ loading: false }); NProgress.done(); }); } render() { const { Component, pageProps } = this.props; return ( <> {this.state.loading && <div className="loader">Loading...</div>} <Component {...pageProps} /> </> ); } } export default MyApp;

In the above example, we set a loading state and update it in response to route events. Then, we use this state in the render method to conditionally display the loading indicator. Additionally, we incorporate NProgress to show a smooth progress bar.

Conclusion

By listening to Next.js route events, you can easily add loading indicators during page transitions. You can implement this with simple state and conditional rendering, or use libraries like NProgress for a more professional loading effect. In any case,

2024年6月29日 12:07 回复

The nextjs-progressbar package makes this extremely simple. In Next.js _app.js (or .jsx, .tsx, etc.), simply add <NextNProgress /> at any position within the default export, as shown below:

shell
import NextNProgress from 'nextjs-progressbar'; export default function App({ Component, pageProps }) { return ( <> <NextNProgress /> <Component {...pageProps} />; </> ); }
2024年6月29日 12:07 回复

你的答案