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

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

更新:

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

示例和反应加载屏幕。


当前回答

我也在我的应用程序中使用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;
    ...
}

其他回答

当你的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,事情就不那么复杂了,因为用户会在页面加载后立即看到真正的应用程序。

我不知道现在回答是否太晚,因为你可能已经找到了解决方案,但这里有一个来自我的观点,因为这个问题真的很有用。: 我在scrimba.com上上了一堂课,在这里,老师从课堂开始,然后开始讲课。他通过课堂和状态来教授API调用。这是他的代码:

import React, {Component} from "react"

class App extends Component {
    constructor() {
        super()
        this.state = {
            loading: false,
            character: {}
        }
    }
    
    componentDidMount() {
        this.setState({loading: true})
        fetch("https://swapi.dev/api/people/1/")
            .then(response => response.json())
            .then(data => {
                this.setState({
                    loading: false,
                    character: data
                })
            })
    }
    
    render() {
        const text = this.state.loading ? "loading..." : this.state.character.name
        return (
            <div>
                <p>{text}</p>
            </div>
        )
    }
}

export default App

这很直接,在开始时将加载状态设置为true并保持它,直到接收到数据,然后当接收到数据时,更改状态并将加载设置为false并显示内容。 现在我试着用钩子,作为练习,它工作得很顺利!一个简单而有效的解决方案。这是我的代码:

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

function App()
{
    const [response, setResponse] = useState([]);
    
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        fetchResponse() ;
    } , []);

    const fetchResponse = async () => {
        const data = await fetch("https://swapi.dev/api/people/1/");
        const response = await data.json();

        setResponse(response);
        console.log(response.name);
        setLoading(false);
    } 

        const content = loading ? <i className="fas fa-atom fa-spin"></i> : <h1>{response.name}</h1>

    return(
        <section id="w-d-p">
            {content}
        </section>
    )
}

export default App;

钩子也是一样的逻辑。在数据加载时,我得到了漂亮的转轮然后,我的数据!

哦,顺便说一下,如果你不喜欢这个XD,你可以在fetch中放入自己的API。

最重要的问题是:“loading”是什么意思?如果你谈论的是被安装的物理元素,这里的一些第一个答案很好。然而,如果你的应用做的第一件事是检查身份验证,你真正加载的是来自后端的数据,用户是否传递了一个cookie,标签他们是授权或未授权的用户。

这是基于redux的,但你可以很容易地将其更改为普通的反应状态模型。

行动的创造者:

export const getTodos = () => {
  return async dispatch => {
    let res;
    try {
      res = await axios.get('/todos/get');

      dispatch({
        type: AUTH,
        auth: true
      });
      dispatch({
        type: GET_TODOS,
        todos: res.data.todos
      });
    } catch (e) {
    } finally {
      dispatch({
        type: LOADING,
        loading: false
      });
    }
  };
};

最后一部分意味着无论用户是否被授权,在收到响应后加载屏幕都会消失。

下面是加载它的组件的样子:

class App extends Component {
  renderLayout() {
    const {
      loading,
      auth,
      username,
      error,
      handleSidebarClick,
      handleCloseModal
    } = this.props;
    if (loading) {
      return <Loading />;
    }
    return (
      ...
    );
  }

  ...

  componentDidMount() {
    this.props.getTodos();
  }

...

  render() {
    return this.renderLayout();
 }

}

如果状态。加载是真实的,我们总是会看到加载屏幕。在componentDidMount上,我们调用getTodos函数,它是一个转换状态的动作创建器。当我们得到一个响应(这可能是一个错误)加载假。我们的组件更新,再次调用渲染,这一次没有加载屏幕,因为if语句。

现在我们也可以在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;

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

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