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

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

更新:

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

示例和反应加载屏幕。


当前回答

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

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

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

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

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

其他回答

当你的React应用程序是巨大的,它真的需要时间来启动和运行后,页面已经加载。比如,你将应用的React部分挂载到#app上。通常,index.html中的这个元素只是一个空的div:

<div id="app"></div>

你可以做的是放一些样式和一堆图像,让它在页面加载和初始React应用程序渲染到DOM之间看起来更好:

<div id="app">
  <div class="logo">
    <img src="/my/cool/examplelogo.svg" />
  </div>
  <div class="preload-title">
    Hold on, it's loading!
  </div>
</div>

页面加载后,用户将立即看到index.html的原始内容。不久之后,当React准备好将呈现的组件的整个层次结构挂载到这个DOM节点时,用户将看到实际的应用程序。

注意class,而不是className。这是因为你需要把它放到html文件中。


如果你使用SSR,事情就不那么复杂了,因为用户会在页面加载后立即看到真正的应用程序。

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

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

如果你使用react-router来管理你的应用程序的路由,你可以很容易地添加加载屏幕与我做的react-router加载库。

它也会影响页面切换,但我认为,如果你想预装第一页,自然也会预装其他页面。

这个方法和悬疑方法的区别在于,有了这个库,你可以在获取数据的同时继续加载。 基本上,这个方法非常类似于在组件中使用isLoading状态,但是如果您有很多不同的页面,则更容易实现。

使用

在路由器部分,从react-router-loading导入Switch和Route,而不是从react-router-dom导入

import { Switch, Route } from "react-router-loading";

<Switch>
    <Route path="/page1" component={Page1} />
    <Route path="/page2" component={Page2} />
    ...
</Switch>

在切换前必须加载的每条路线上添加加载道具

<Switch>
    // data will be loaded before switching
    <Route path="/page1" component={Page1} loading />

    // instant switch as before
    <Route path="/page2" component={Page2} />
    ...
</Switch>

在加载道具路由中提到的组件的初始加载方法的末尾添加loadingContext.done()(在这种情况下是Page1)

import { LoadingContext } from "react-router-loading";
const loadingContext = useContext(LoadingContext);

const loading = async () => {
    // loading some data

    // call method to indicate that loading is done and we are ready to switch
    loadingContext.done();
};

你可以指定加载屏幕,将显示在你的应用程序的第一次加载

const MyLoadingScreen = () => <div>Loading...</div>

<Switch loadingScreen={MyLoadingScreen}>
...
</Switch>

现在我们也可以在React 16.8中使用钩子:

import React, { useState, useEffect } from 'react';

const App = () => {
  const [ spinner, setSpinner ] = useState(true);

  // It will be executed before rendering

  useEffect(() => {
    setTimeout(() => setSpinner(false), 1000)
  }, []);

  // [] means like componentDidMount

  return !spinner && <div>Your content</div>;
};

export default App;

在公用文件夹中编辑index.html文件的位置。复制你的图像到相同的位置index.html在公共文件夹。 然后将index.html中包含<div id="root"> </div>标签的部分内容替换为下面给定的html代码。

<div id="root">  <img src="logo-dark300w.png" alt="Spideren" style="vertical-align: middle; position: absolute;
   top: 50%;
   left: 50%;
   margin-top: -100px; /* Half the height */
   margin-left: -250px; /* Half the width */" />  </div>

在加载过程中,Logo现在将出现在页面中间。并将在几秒钟后被React替换。