下一个js页面转换时的加载屏幕

Mul*_*yan 2 reactjs next.js

我试图在Nextjs应用程序中更改路线时实现一个加载屏幕,例如/ home-> / about。

我当前的实现如下。我将初始加载状态设置为false,然后在componentDidMount上进行更改。我也调用Router.events.on内部功能componentDidMount路由变化开始时改变负荷状态。

_app.js在页面文件夹中

class MyApp extends App {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false,
    };
  }

  componentDidMount() {
    this.setState({ loaded: true });
    Router.events.on('routeChangeStart', () => this.setState({ loaded: false }));
    Router.events.on('routeChangeComplete', () => this.setState({ loaded: true }));
  }



  render() {
    const { Component, pageProps } = this.props;

    const { loaded } = this.state;

    const visibleStyle = {
      display: '',
      transition: 'display 3s',
    };
    const inVisibleStyle = {
      display: 'none',
      transition: 'display 3s',
    };
    return (
      <Container>
        <>
          <span style={loaded ? inVisibleStyle : visibleStyle}>
            <Loader />
          </span>
          <span style={loaded ? visibleStyle : inVisibleStyle}>
            <Component {...pageProps} />
          </span>
        </>
      </Container>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

这工作得很好,但是我觉得可能会有更好的解决方案,更优雅的解决方案。这是实现此加载功能的唯一麻烦方法,还是有替代方法?

arc*_*ger 66

(编辑:如果您使用的是 App Router,请参阅下面 Jeremy Bernier 的评论

对于 2023 年遇到此问题(并使用旧页面路由器)的任何人来说,nextjs-progressbar包使这变得超级简单。在 Next.js _app.js(或.jsx.tsx等)中,只需在默认导出中的任意位置添加`,如下所示:

import NextNProgress from 'nextjs-progressbar';

export default function App({ Component, pageProps }) {
  return (
    <>
      <NextNProgress />
      <Component {...pageProps} />;
    </>
  );
}
Run Code Online (Sandbox Code Playgroud)

并做了!

演示及截图: 在此输入图像描述

  • 不适用于新的 App Router,但此软件包可以使用:“nextjs-toploader”(https://www.npmjs.com/package/nextjs-toploader) (5认同)

Roh*_*nan 31

使用新的钩子 api,这就是我要做的..

function Loading() {
    const router = useRouter();

    const [loading, setLoading] = useState(false);

    useEffect(() => {
        const handleStart = (url) => (url !== router.asPath) && setLoading(true);
        const handleComplete = (url) => (url === router.asPath) && setLoading(false);

        router.events.on('routeChangeStart', handleStart)
        router.events.on('routeChangeComplete', handleComplete)
        router.events.on('routeChangeError', handleComplete)

        return () => {
            router.events.off('routeChangeStart', handleStart)
            router.events.off('routeChangeComplete', handleComplete)
            router.events.off('routeChangeError', handleComplete)
        }
    })
    
    return loading && (<div>Loading....{/*I have an animation here*/}</div>);
}
Run Code Online (Sandbox Code Playgroud)

现在<Loading/>将在路线发生变化时显示...我使用 react-spring 制作动画,但您可以使用任何您喜欢的库来执行此操作。

你甚至可以采取进一步的步骤和修改时,组件显示了通过修改handleStarthandleComplete方法是得到了url

  • 你好,我想看看这是如何在完整的 _app.js 组件中实现的。如果您能好心地发布该文件的链接,我将不胜感激。 (4认同)
  • handleComplete 中的 `router.asPath` 似乎没有及时解析到目标路径。所以我决定不比较 `setLoading` 之前的 url,它可以工作。 (4认同)
  • 如果使用动态路由,似乎使用“router.asPath”而不是“router.pathname”更准确。 (2认同)
  • 由于某种原因,这对我不起作用。第一次加载后,“loading”始终为 true。 (2认同)

Mej*_*jan 11

NProgress 的新更新:

import Router from 'next/router'
import Link from 'next/link'
import Head from 'next/head'
import NProgress from 'nprogress'

Router.events.on('routeChangeStart', (url) => {
  console.log(`Loading: ${url}`)
  NProgress.start()
})
Router.events.on('routeChangeComplete', () => NProgress.done())
Router.events.on('routeChangeError', () => NProgress.done())

export default function App({ Component, pageProps }) {
  return (
    <>
      <Head>
        {/* Import CSS for nprogress */}
        <link rel="stylesheet" type="text/css" href="/nprogress.css" />
      </Head>
      <Component {...pageProps} />
    </>
  )
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 Tailwind CSS,请从此处复制代码:https ://unpkg.com/nprogress@0.2.0/nprogress.css 并将代码粘贴到您的全局 CSS 文件中。

如果要禁用微调器,请在_app.tsx/jsx文件中添加以下代码并从 CSS 中删除微调器样式。

NProgress.configure({ showSpinner: false });
Run Code Online (Sandbox Code Playgroud)

来源链接:

  • 为了以防万一,你必须将“nprogress.css”保存在“/public”中 (2认同)

MoH*_*oHo 6

为什么不使用nprogress如下_app.js

import React from 'react';
import Router from 'next/router';
import App, { Container } from 'next/app';
import NProgress from 'nprogress';

NProgress.configure({ showSpinner: publicRuntimeConfig.NProgressShowSpinner });

Router.onRouteChangeStart = () => {
  // console.log('onRouteChnageStart triggered');
  NProgress.start();
};

Router.onRouteChangeComplete = () => {
  // console.log('onRouteChnageComplete triggered');
  NProgress.done();
};

Router.onRouteChangeError = () => {
  // console.log('onRouteChnageError triggered');
  NProgress.done();
};

export default class MyApp extends App { ... }
Run Code Online (Sandbox Code Playgroud)

链接到nprogress

您还需要包括样式文件。如果将css文件放在static目录中,则可以按以下方式访问样式:

<link rel="stylesheet" type="text/css" href="/static/css/nprogress.css" />
Run Code Online (Sandbox Code Playgroud)

确保CSS在所有页面中都可用...

它适用于所有更改路线。

  • 对于将来阅读本文的人,您可以通过从 nprogress.css(在 node_modules 内)复制样式并将其粘贴到您自己的 CSS/SCSS 文件中来更改 CSS,然后导入您的 CSS 文件而不是您的 _app 中的 nprogress.css 文件。 js。你可以摆弄 CSS,因为动画非常基本。 (3认同)
  • 对于使用 Next.js 的人来说,现在有这个:https://www.npmjs.com/package/nextjs-progressbar (2认同)