首页 > 解决方案 > 在没有 API 调用或设置超时的情况下在登录页面中显示和隐藏加载程序?

问题描述

我在使用 redux 的反应应用程序中苦苦挣扎,搜索了很多但没有得到所需的解决方案,这就是我在这里发布问题的原因,所以我的问题是我必须在页面加载时显示加载器HTML加载加载器应该隐藏,下面是我的代码

class LoginScreen extends React.Component {
  state = {
    email: '',
    password: '',
    stayLoggedIn: false,
    isLoading: true
  };

  componentDidMount() {
    setTimeout(() => {
      this.setState({ isLoading: false });
   }, 2000);
  }

渲染基于isLoading但目前我已经使用 set-timeout 显示和隐藏加载器我想知道是否有任何解决方案可以使其在没有 set-timeout 的情况下工作,任何帮助都是可观的。

标签: reactjsreduxreact-redux

解决方案


  1. setTimeout只是一个异步操作,当你调用 setState 函数时,React 会比较旧状态和新状态,并根据新状态触发对你的组件的渲染。

  2. 当你的组件有一个本地状态时,你将 redux 状态作为 props 注入到你的组件中,这样当你有本地状态时不会触发渲染,你需要使用componentWillReceiveProps方法并调用setState方法来改变你的本地状态setState根据新的道具使用状态。

    注意:componentWillReceiveProps方法工作直到React v17

import React from "react";
import ReactDOM from "react-dom";

const delay = async ms => await new Promise(resolve => setTimeout(resolve, ms));

class Loader extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false
    };
  }

  componentWillReceiveProps(nextProps) {
    this.setState({ isLoading: nextProps.isLoading });
  }

  render() {
    return (
      <div style={{ border: "1px solid #999", padding: "10px" }}>
        Loader component
        <div>Loading: {String(this.state.isLoading)}</div>
      </div>
    );
  }
}

class LoginScreen extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: false
    };
  }

  async asyncOperation() {
    // Show loader
    this.setState({ isLoading: true });

    // Async operation, like fetch, etc...
    await delay(1000);

    // Hide loader
    this.setState({ isLoading: false });
  }

  render() {
    return (
      <div>
        <Loader isLoading={this.state.isLoading} />
        <br />
        <button
          onClick={this.asyncOperation.bind(this)}
          disabled={this.state.isLoading}
        >
          {this.state.isLoading ? "Waiting..." : "Call async operation"}
        </button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<LoginScreen />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


推荐阅读