NextJS: Как я могу использовать загрузочный компонент вместо nprogress? - PullRequest
0 голосов
/ 22 января 2019

Можно ли использовать <Loading /> компонент в NextJS вместо nprogress? Я думаю, что вам нужно было бы получить доступ к некоторым реквизитам высокого уровня, таким как pageProps из событий маршрутизатора, чтобы вы могли переключать состояние загрузки и затем условно выводить компонент загрузки, но я не вижу способа сделать это ...

Например,

Router.events.on("routeChangeStart", (url, pageProps) => {
  pageProps.loading = true;
});

и в рендере

const { Component, pageProps } = this.props;

return pageProps.loading ? <Loading /> : <Page />;

Но, конечно, routeChangeStart не передает pageProps.

1 Ответ

0 голосов
/ 09 февраля 2019

Да, вместо nProgress можно использовать другой компонент для обработки загрузки.У меня был похожий вопрос, и я обнаружил, что решение ниже работает для меня.

Имеет смысл сделать все это в ./pages/_app.js, потому что согласно документации , которая может помочь с сохранениеммакет и состояние между страницами.Вы можете инициировать события Маршрутизатора в методе жизненного цикла componentDidMount.Важно отметить, что _app.js монтируется только один раз, но инициация событий маршрутизатора все равно будет работать здесь.Это позволит вам установить состояние.

Ниже приведен пример того, как все это объединяется:

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;
...