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

Можно ли использовать компонент <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.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
4 173
2

Ответы 2

Да, можно использовать другой компонент для обработки загрузки вместо 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.info('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;

Используйте хук ниже, чтобы проверить состояние загрузки маршрутизатора:

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
}

Это действительно хорошее решение @duan. Возможно, его можно расширить, чтобы показать ошибку и статус ошибки? Что-то вроде: gist.github.com/adamduncan/2e5b9c2eafe74fd9fda902a6ea213ba3

adamduncan 16.01.2021 19:57

Другие вопросы по теме

Как отображать значение в режиме реального времени без обновления страницы с помощью React и SocketIO?
Как сохранить значение функции в переменной nodejs server get-folder-size
TypeError: Не удается прочитать свойство «push» неопределенного, я не могу отправить комментарии в массив данных
Как я могу аутентифицировать электронную почту с помощью nodejs? Я получаю электронное письмо для отправленного пользователем электронного письма, затем я щелкаю ссылку на своем конце, чтобы подтвердить это электронное письмо
База данных Firebase Get All Value In Order Облачные функции
Повестка дня nodeJS запускает работу в определенную дату
Как исправить предупреждения о зависимостях одноранговых узлов после обновления приложения Angular с версии 6 до 7
Как использовать $lte с псевдонимом?
Как запросы списка браузеров объединяются в многострочной конфигурации списка браузеров?
Вернуть значение из socket.io на сторону клиента