create-react-app: как загрузить html перед рендерингом React

Я пытаюсь добавить заставку перед загрузкой React.

так как я использую реагирующие сценарии / реагирующее приложение, мой index.tsx имеет только эту часть:

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

я попытался добавить свой собственный div на той же странице, но он не отображается.

я хотел бы отобразить простой пустой экран с моим изображением-заставкой на 1-секундном таймере, прежде чем реагировать на загрузку, чтобы избежать/скрыть смещение элементов рендеринга.

** если я добавлю экран в app.tsx, смещение произойдет до загрузки экрана

обновить

как указал Ришаб ниже, index.html находится в папке /public. В итоге я объединил 2 подхода.

  1. добавить экран перед запуском реакции:

    <div id="root">
      <div id="dimScreen">
        <img src="/img/logo.png" />
      </div>
    </div>
    
  2. 2.

загрузка правильного загрузчика без верха в течение 0,5–1 с

class App extends Component {
    state = {
        loading: true
    }
    componentDidMount() {
        setTimeout(() => {
            this.setState({ loading: false });
        }, 1000);
    }
    render() {
        return (
            <React.Fragment>
                {
                    this.state.loading ?
                        <Loader />
                        : (
                            <div className="app">
                                <Header />
                                <MyComponent />
                            </div>
                        )
                }
            </React.Fragment>
        );
    }
}

пока этот подход работает лучше всего, но будет обновляться, если я найду проблемы или что-то лучше


person Sonic Soul    schedule 19.03.2019    source источник
comment
Что вы имеете в виду под смещением? Почему бы вам не иметь что-то вроде переменной isLoading в состоянии и условно отображать ваше приложение? Например, если он загружается, отображать нуль или заставку, а когда все готово, отображать полное приложение?   -  person Hamed    schedule 19.03.2019
comment
Фрагмент во втором решении в этом посте также может помочь: stackoverflow.com/a/40989121/9598077   -  person Hamed    schedule 19.03.2019


Ответы (3)


Это пример показа загрузчика на пять секунд с использованием state и setTimeout(). Вместо <Loader/> можно указать splash screen component.

import React, { Component } from 'react';

import Drawer from '../Drawer/Drawer';
import Loader from '../../components/UI/Spinner/Loader/Loader';

class App extends Component {
  state = {
    loading: true
  }

  componentDidMount(){
    setTimeout(() => {
      this.setState({loading: false});
    }, 5000);
  }

  render() {  
    return (
      <React.Fragment>
        {
          this.state.loading ? <Loader />: <Drawer />
        }
      </React.Fragment>
    );
  }
}

export default App;

Я надеюсь, что это помогает!

person Avinash Mahlawat    schedule 19.03.2019
comment
пока это работает намного лучше, чем мой html-загрузчик! - person Sonic Soul; 20.03.2019

Так что просто зайдите в свой index.html внутри вашей общей папки и внутри

<div id="root"><-- Add Splash screen html code here --></div>

добавьте код заставки, когда реакция загружается, он заменяет все содержимое внутри div корневым идентификатором

person Rishabh Rawat    schedule 19.03.2019
comment
нет index.html. это приложение для реагирования, которое генерирует index.tsx. я уже пытался добавить туда свою заставку, как указано в моем вопросе - person Sonic Soul; 19.03.2019
comment
Стоит упомянуть: если вы создаете PWA и хотите иметь изображение внутри index.html, <div id="root"> используйте SVG или конвертируйте изображение в base64 и используйте URI данных. Это гарантирует, что изображение окажется в автоматически сгенерированном манифесте перед кэшированием, поскольку данные встраиваются непосредственно в index.html, а не в отдельный файл изображения. - person cnanders; 21.10.2019

Я не уверен, что это вообще сработает, это не проверено, но, может быть, это приведет вас в правильном направлении? Итак, вот мои 2 цента

с Splash.js

const withSplash = MyAppComponent => 
  class extends React.Component {
    state = {
      showSplash: true
    }

    componentDidMount () {
      handleSplashComponent(); 
    }

    componentWillUnmount () {
      if (this.timer) {
        this.timer = null;
      }
    }

    handleSplashComponent = () => {
      this.timer = setTimeout(()=> {
        this.setState({
          showSplash: false
        })
      }, 3000)
    }

    render () {
      return this.state.showSplash
        ? <SplashComponent />
        : <MyAppComponent />
    }
  }

App.js

class App extends Component {
  ...
}

export default withSplash(App);

ДругойКомпонент.js

class AnotherComponent extends Component {
  ...
}

export default withSplash(AnotherComponent);
person Shawn Yap    schedule 19.03.2019
comment
Спасибо! я пробовал этот маршрут, но к тому времени, когда код реакции выполняется слишком поздно. мне нужно было что-то более срочное. решение в index.html работает очень хорошо - person Sonic Soul; 19.03.2019
comment
на самом деле решение index.html все еще дергается :( сейчас я попробую ваш подход - person Sonic Soul; 19.03.2019
comment
эй, эй, специально еще не пробовал, так как другой был похож, и он работал, но похоже, что он будет работать так же! - person Sonic Soul; 20.03.2019