Sonic Soul
Sonic Soul

Reputation: 24939

create-react-app: how to load html before React renders

I am trying to add a splash screen before React loads.

since i am using react scripts / react-app my index.tsx only has this part:

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

i tried adding my own div on the same page but it doesn't show.

i would like to display a simple blank screen with my splash image on a 1 second timer before react loads to avoid/hide the shifting of the rendering elements.

** if i do add the screen in app.tsx, the shifting happens before the screen loads

update

as Rishabh pointed out below, index.html is in /public folder. So I ended up combining 2 approaches.

  1. add a screen before react starts:

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

loading a proper loader non top for .5 - 1 sec

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>
        );
    }
}

so far this approach is working best but will update if i find issues or something better

Upvotes: 0

Views: 2234

Answers (3)

Shawn Yap
Shawn Yap

Reputation: 969

I'm not sure if this will work at all, it's not tested but maybe it'll lead you to the right direction? So, here's my 2 cents

withSplash.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);

AnotherComponent.js

class AnotherComponent extends Component {
  ...
}

export default withSplash(AnotherComponent);

Upvotes: 0

Engineer
Engineer

Reputation: 1261

This is an example to show loader for five seconds using state and setTimeout(), In place of <Loader/> you can give 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;

i hope it helps!

Upvotes: 1

Rishabh Rawat
Rishabh Rawat

Reputation: 859

So just go to your index.html inside your public folder and inside

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

add your splash screen code, when react loads it replaces all the content inside the div with id root

Upvotes: 2

Related Questions