NextJS:如何为生产构建添加屏幕加载?

NextJS: How to add screen loading for production build?

我想在下一个 js 项目中添加屏幕加载。我尝试使用 next/router.

中的 Router 组件来做到这一点

这是我在 next.js 项目中的 _app.js:

import {CookiesProvider} from 'react-cookie';
import App from 'next/app'
import React from 'react'
import {Provider} from 'react-redux'
import withRedux from 'next-redux-wrapper'
import withReduxSaga from 'next-redux-saga'
import createStore from '../src/redux/store'
import Router from "next/router";
import {Loaded, Loading} from "../src/util/Utils";

class MyApp extends App {

    static async getInitialProps({Component, ctx}) {
        let pageProps = {};

        if (Component.getInitialProps) {
            pageProps = await Component.getInitialProps({ctx})
        }

        return {pageProps}
    }

    render() {
        Router.onRouteChangeStart = () => {
            Loading()
        };

        Router.onRouteChangeComplete = () => {
            Loaded()
        };

        Router.onRouteChangeError = () => {
            Loaded()
        };

        const {Component, pageProps, store} = this.props;
        return (
            <CookiesProvider>
                <Provider store={store}>
                    <Component {...pageProps} />
                </Provider>
            </CookiesProvider>
        )
    }
}

export default withRedux(createStore)(withReduxSaga(MyApp))

这是Loaded()Loading()函数:

export const Loaded = () => {
    setTimeout(() => {
        let loading = 'has-loading';
        document.body.classList.remove(loading);
    }, 100);
};

export const Loading = () => {
    let loading = 'has-loading';
    document.body.classList.add(loading);
};

当项目处于开发模式时,代码运行良好。但是在构建项目的时候,loading不会消失。

您知道这个问题的解决方案还是建议其他解决方案?

使用 apollo clientreact hooks 你可以按照下面的方式做。

示例:

import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';

import { withApollo } from '../lib/apollo';
import UserCard from '../components/UserCard';

export const USER_INFO_QUERY = gql`
  query getUser ($login: String!) {
    user(login: $login) {
      name
      bio
      avatarUrl
      url
    }
  }
`;

const Index = () => {
  const { query } = useRouter();
  const { login = 'default' } = query;
  const { loading, error, data } = useQuery(USER_INFO_QUERY, {
    variables: { login },
  });

  if (loading) return 'Loading...';            // Loading component
  if (error) return `Error! ${error.message}`; // Error component

  const { user } = data;

  return (
    <UserCard
      float
      href={user.url}
      headerImg="example.jpg"
      avatarImg={user.avatarUrl}
      name={user.name}
      bio={user.bio}
    />
  );
};

export default withApollo({ ssr: true })(Index);

更多信息在这里:https://github.com/zeit/next.js/tree/canary/examples/with-apollo

我在包装器组件中添加了以下代码,问题得到解决。

componentDidMount() {
    Loaded();
}

componentWillUnmount() {
    Loading();
}