这是一个来自谷歌Adsense应用页面的例子。加载界面显示在主界面之前。

我不知道如何用React做同样的事情,因为如果我用React组件渲染加载屏幕,它不会在页面加载时显示,因为它必须等待DOM渲染之前。

更新:

我通过将屏幕加载器放在index.html中并在React componentDidMount()生命周期方法中删除它来举例说明我的方法。

示例和反应加载屏幕。


当前回答

The starting of react app is based on the main bundle download. React app only starts after the main bundle being downloaded in the browser. This is even true in case of lazy loading architecture. But the fact is we cannot exactly state the name of any bundles. Because webpack will add a hash value at the end of each bundle at the time when you run 'npm run build' command. Of course we can avoid that by changing hash settings, but it will seriously affect the cache data problem in the Browser. Browsers might not take the new version because of the same bundle name. . we need a webpack + js + CSS approach to handle this situation.

更改public/index.html如下所示

<!DOCTYPE html> <html lang="en" xml:lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=3.0, shrink-to-fit=no"> <meta name="theme-color" content="#000000"> <!-- manifest.json provides metadata used when your web app is added to the homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <style> .percentage { position: absolute; top: 50%; left: 50%; width: 150px; height: 150px; border: 1px solid #ccc; background-color: #f3f3f3; -webkit-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); transform: translate(-50%, -50%); border: 1.1em solid rgba(0, 0, 0, 0.2); border-radius: 50%; overflow: hidden; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .innerpercentage { font-size: 20px; } </style> <script> function showPercentage(value) { document.getElementById('percentage').innerHTML = (value * 100).toFixed() + "%"; } var req = new XMLHttpRequest(); req.addEventListener("progress", function (event) { if (event.lengthComputable) { var percentComplete = event.loaded / event.total; showPercentage(percentComplete) // ... } else { document.getElementById('percentage').innerHTML = "Loading.."; } }, false); // load responseText into a new script element req.addEventListener("load", function (event) { var e = event.target; var s = document.createElement("script"); s.innerHTML = e.responseText; document.documentElement.appendChild(s); document.getElementById('parentDiv').style.display = 'none'; }, false); var bundleName = "<%= htmlWebpackPlugin.files.chunks.main.entry %>"; req.open("GET", bundleName); req.send(); </script> <!-- Notice the use of %PUBLIC_URL% in the tags above. It will be replaced with the URL of the `public` folder during the build. Only files inside the `public` folder can be referenced from the HTML. Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> <title>App Name</title> <link href="<%= htmlWebpackPlugin.files.chunks.main.css[0] %>" rel="stylesheet"> </head> <body> <noscript> You need to enable JavaScript to run this app. </noscript> <div id="parentDiv" class="percentage"> <div id="percentage" class="innerpercentage">loading</div> </div> <div id="root"></div> <!-- This HTML file is a template. If you open it directly in the browser, you will see an empty page. You can add webfonts, meta tags, or analytics to this file. The build step will place the bundled scripts into the <body> tag. To begin the development, run `npm start` or `yarn start`. To create a production bundle, use `npm run build` or `yarn build`. --> </body> </html>

在你的webpack产品配置中,将HtmlWebpackPlugin选项改为如下

 new HtmlWebpackPlugin({
          inject: false,
...

您可能需要使用'eject'命令来获取配置文件。最新的webpack可能有选项配置HtmlWebpackPlugin而不弹出项目。

其他回答

我也在我的应用程序中使用React。对于请求,我使用axios拦截器,所以让加载器屏幕的好方法(fullpage,因为你展示了一个例子)是在拦截器内部添加类或id为例(这里的代码来自官方文档,一些自定义代码):

// Add a request interceptor
axios.interceptors.request.use(function (config) {
    // Do something before request is sent
     document.body.classList.add('custom-loader');
     return config;
  }, function (error) {
    // Do something with request error
    return Promise.reject(error);
  });

// Add a response interceptor
axios.interceptors.response.use(function (response) {
    // Do something with response data
       document.body.classList.remove('custom-loader');
       return response;
  }, function (error) {
    // Do something with response error
    return Promise.reject(error);
  }); 

然后在CSS中使用伪元素实现你的加载器(或添加类或id到不同的元素,而不是你喜欢的body) -你可以设置背景的颜色为不透明或透明,等等…例子:

custom-loader:before {
    background: #000000;
    content: "";
    position: fixed;
    ...
}

custom-loader:after {
    background: #000000;
    content: "Loading content...";
    position: fixed;
    color: white;
    ...
}

解决这个问题的方法是在你的渲染函数中这样做:

constructor() {
    this.state = { isLoading: true }
}

componentDidMount() {
    this.setState({isLoading: false})
}

render() {
    return(
        this.state.isLoading ? *showLoadingScreen* : *yourPage()*
    )
}

在构造函数中将isLoading初始化为true,在componentDidMount上将其初始化为false。

你可以通过在react中使用惰性加载轻松做到这一点。 为此你必须使用惰性和悬疑反应。

import React, { lazy, Suspense } from 'react';

const loadable = (importFunc, { fallback = null } = { fallback: null }) => {
  const LazyComponent = lazy(importFunc);

  return props => (
    <Suspense fallback={fallback}>
      <LazyComponent {...props} />
    </Suspense>
  );
};

export default loadable;

然后像这样导出你的组件。

export const TeacherTable = loadable(() =>
  import ('./MainTables/TeacherTable'), {
    fallback: <Loading />,
  });

然后在你的路由文件中像这样使用它。

 <Route exact path="/app/view/teachers" component={TeacherTable} />

这就是现在你很好去每次你的DOM渲染你的加载组件将显示为我们已经在上面的fallback属性中指定。只要确保你只在componentDidMount()中做任何ajax请求

我使用的是react-progress-2 npm包,它是零依赖的,在ReactJS中工作得很好。

https://github.com/milworm/react-progress-2

安装:

NPM安装react-progress-2

在项目中包含react-progress-2/main.css。

导入“node_modules / react-progress-2 / main.css”;

包括react-progress-2,并把它放在顶部组件的某个地方,例如:

import React from "react";
import Progress from "react-progress-2";

var Layout = React.createClass({
render: function() {
    return (
        <div className="layout">
            <Progress.Component/>
                {/* other components go here*/}
            </div>
        );
    }
});

现在,无论何时你需要显示一个指示器,只需调用Progress.show(),例如:

loadFeed: function() {
    Progress.show();
    // do your ajax thing.
},

onLoadFeedCallback: function() {
    Progress.hide();
    // render feed.
}

请注意,show和hide调用是堆叠的,因此在n个连续的show调用之后,您需要执行n个hide调用来隐藏一个指示器,或者您可以使用Progress.hideAll()。

这可以通过在html文件(例如index.html)中放置加载图标来实现,这样用户就可以在html文件加载后立即看到图标。

当你的应用程序完成加载时,你可以简单地删除生命周期钩子中的加载图标,我通常在componentDidMount中这样做。