Different approach to loading screen in React

Kuba - May 30 '21 - - Dev Community

Most of the loading screens I saw, based on boolean variable loading. Then based on it, component loadingScreen is returned or the actual page. The more data I wanted to load, the more if statements I had to make to check if I am still loading. More such ifs sounds like a bad idea to me 🤷‍♀️.

I wanted to make my LoadingScreen component smart enough to figure out, if it should be still displayed.

Let's keep loading screen simple for this example. If it has children, display them. Else, use default loader.

// LoadingScreen.js
const LoadingScreen = (props) => {
return (
        <div class="bg-gray-600 h-screen w-screen fixed">
            {
                props.children? (
                    <div>
                        {props.children}
                    </div>
                ):(
                    <div>Default loader...</div>
                )
            }
        </div>
    )
}

Enter fullscreen mode Exit fullscreen mode

Since loader has to decide if data is already loaded, it needs to have access to those data. From the main component point of view it will look like this.

// MainPage.js
const MainPage = (props) => {
    const [data, setData] = useState(undefined);

    useEffect(() => {
        if(typeof props.data !== 'undefined'){
            var keyValuePairs = Object.values(props.data).map((key) => <li key={key}>{key}</li>);
            setData(keyValuePairs);
        }else{
            props.makeRequest();
        }
    }, [props.data])

    return (
        <>
            <LoadingScreen toLoad={[data]}/>
            <div>
                <h2>Conent:</h2>
                <div>
                    {data}
                </div>
            </div>

        </>
    )
}

const mapStateToProps = (state) => {
    return {
        data: state.main.data
    }
}

const mapDispatchToProps = dispatch => ({
    makeRequest: () => dispatch(getData());
})

Enter fullscreen mode Exit fullscreen mode

The simplest way of checking if data is already loaded, is checking if all elements in array toLoad are not undefined.

Let's add such check to LoadingScreen component.

// LoadingScreen.js
const LoadingScreen = (props) => {

    const isDataLoaded = () => {
        for(var i in props.toLoad){
            if(typeof props.toLoad[i] === 'undefined'){
                return false;
            }
        }
        return true;
    }

    return (
        isDataLoaded() ? (
            null
        ):(
            <div class="bg-gray-600 h-screen w-screen fixed">
                {
                    props.children? (
                        <div>
                            {props.children}
                        </div>
                    ):(
                        <div>Default loader...</div>
                    )
                }
            </div>
        )
    )
}

Enter fullscreen mode Exit fullscreen mode

And that's it! LoadingScreen will be displayed till data will stay undefined. Another approach is to check if data is equal to it's initial state.

// MainPage.js
<LoadingScreen toLoad={[data]} toLoadInitialState={[initialData]}/>
Enter fullscreen mode Exit fullscreen mode

And the check will be:

// LoadingScreen.js 

const isDataLoaded = () => {
    for(var i in props.toLoad){
        if(props.toLoad[i] === props.toLoadInitialState[i]){
            return false;
        }
    }
    return true;
}
Enter fullscreen mode Exit fullscreen mode

Of course the problem will be when obtained data will be equal initial data but in most of my cases it does the job.

It is about one month since I started to learn React so feel free to point out any rookie mistake I made 😉.

. . . . . . . . . . . . . . . . . . . . .
Terabox Video Player