Показать и скрыть загрузчик на целевой странице без вызова API или тайм-аута реакции? - PullRequest
0 голосов
/ 30 октября 2019

Я боролся где-то в приложении реагирования с редуксом, много искал, но не нашел нужного решения, поэтому я отправляю вопрос здесь, поэтому моя проблема в том, что я должен показывать загрузчик, когда страница загружается икогда весь загрузчик HTML должен быть скрыт, ниже мой код

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

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

рендеринг HTML на основе isLoading, но в настоящее время я использовал set-timeout show и скрыл загрузчик, который я хочу знать, есть лирешение, чтобы заставить его работать без установленного тайм-аута, любая помощь будет заметна.

Ответы [ 2 ]

0 голосов
/ 30 октября 2019

Если я правильно понял, «когда весь HTML загружается», вы хотите показать загрузчик, пока ваше приложение реагирует на браузер. для этого вы можете сделать следующее:

1 - Если вы загрузили свой проект с помощью Create React App - Перейдите в общую папку, есть файл с именем index.html - Он будет содержать элемент <div> ввсе ваше приложение реагирует на веб-упаковщик, который в этом случае будет веб-пакетом. - Внутри этого div напишите загрузчик, подобный этому

   <div id="root">
    <section class="loader">
      <h1 class="heading">INITIALIZING</h1>
      <p class="sub-heading">bear with us ...</p>
    </section>
  </div>

Итак, что происходит здесь, когда вы пишете этот фрагмент кода

ReactDOM.render(<App />, document.getElementById('root'));

Это в основном вводит вашРеагируйте приложение в этот корневой элемент документа, и как только ваше приложение будет упаковано, весь html загружается в браузер и внедряется в этот div, он заменит ваш загрузчик, и ваша страница входа будет видна

И вотCSS для анимации загрузчика

<style>
.loader {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: #fff;
  color: #000;
  overflow-y: hidden;
}

.loader .heading {
  font-size: 36px;
  text-align: center;
  animation: heart-beat 4s infinite ease-in;
  z-index: 1;
}

.loader .sub-heading {
  font-size: 18px;
  text-align: center;
  color: #4b4b4b;
  z-index: 1;
}

@keyframes heart-beat {
  0% {
    opacity: 0.1;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.1;
  }
}

</style>

2- Второй вариант - создать приложение реагирования без CRA, но в этом случае у вас снова будет index.html, и вы сможете повторить вышеуказанные шаги.

0 голосов
/ 30 октября 2019
  1. setTimeout - это просто асинхронная операция, когда вы вызываете функцию setState, React сравнивает старое состояние и новое состояние и запускает рендеринг для вашего компонента на основе нового состояния.

  2. Когда у вас есть локальное состояние для вашего компонента, вы вводите избыточное состояние в качестве реквизита для вашего компонента, таким образом, не запускайте рендеринг, когда у вас есть локальное состояние, вам нужно использовать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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...