0

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

2
  • What do you mean by shifting? Why don't you have something like isLoading variable in the state and conditionally render your the app? Like if it is loading then display null or a splash screen and once you have all the stuff ready display the full App? Commented Mar 19, 2019 at 15:18
  • The snippet in the second solution in this post might also help: stackoverflow.com/a/40989121/9598077 Commented Mar 19, 2019 at 15:23

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

2 Comments

there is no index.html. this is a react app that generates index.tsx. i already tried adding my splash page there as indicated in my question
Worth mentioning - if you are building a PWA and want to have an image inside index.html <div id="root"> use SVG or convert your image to base64 and use a data URI. This ensures that the image ends up in the auto-generated pre-cache manifest, as the data is directly embedded into index.html, rather than in a separate image file.
1

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!

1 Comment

so far this is working out much better than my html loader!
0

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

3 Comments

thanks! i tried this route but by the time react code executes its too late. i needed something more immediate. the solution in index.html works very well
actually the index.html solution is still jerky :( i will try your approach now
hey hey have not tried specifically yet as the other was similar and it worked, but looks like it would work the same!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.