0

I'm using React hooks and i want my component to actually do the entire loading before displaying it.

My current solution is currently this:

import React, {useState, useEffect} from 'react'
import Main from './Main'

export default function Container() {

     const [isLoading, setisLoading] = useState(false);

     useEffect(() => {
        setTimeout(() => setisLoading(true), 1000)
     })

return (
        <div>
           {(isLoading) ? <Main/> : <h1>I'm currently loading</h1>}
        </div>
      );
}

The issue here is that it load's for 1 second and then displays my Main.js component which takes ~2 seconds to load. I want the actually loading to be done before it displays the component.

Arasto
  • 471
  • 6
  • 25

3 Answers3

1

You can try react lazy loading

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );
}
Hải Bùi
  • 2,492
  • 2
  • 9
  • 17
1

What you have is fine, you just have the loading state backwards. Set loading to true by default and then set it to false after 1000ms.

When loading is true, display your loading message, then display your component.

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function Main() {
  return <h1>I'm a main component</h1>;
}

export default function Container() {
  const [isLoading, setisLoading] = useState(true);

  useEffect(() => {
    setTimeout(() => setisLoading(false), 1000);
  });

  return <div>{isLoading ? <h1>I'm currently loading</h1> : <Main />}</div>;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Container />, rootElement);
Tom
  • 2,543
  • 3
  • 21
  • 42
0

You should set up the right variant of importing and code splitting.

The good guide and library for it you can find here: https://github.com/jamiebuilds/react-loadable

If you want to create it on your own, you can write code like that:

export default function Container() {

     const [Main, setMain] = useState(null);

     useEffect(() => {
           import('/path/to/main').then(main => setMain(main));
     }, [])

return (
        <div>
           {(isLoading) ? <Main/> : <h1>I'm currently loading</h1>}
        </div>
      );
}

This variant works both on clientside and serverside.

You also can use React.lazy, but it doesn't work with serverside rendering

Nik
  • 2,170
  • 1
  • 14
  • 20