React loader component increases page loading time rather than showing itself when the page is loading

Viewed 26

I have a page that is making a few heavy API calls when loading, it takes around 5-7 seconds to collect all the data. I referenced [this question] and decided to add a loader with setTimeout to simulate additional "API calls" and timed loading time with and without the loader.

Without the loader it took - 6.92 secs

With the loader it took - 14.05 secs

This is my code:

    const [loading, setLoading] = useState(false);

    useEffect(() => {
        async function updateUI() {
            const ethers_owner = await administrativeSidechainContract.owner()
            setContractOwner(() => {
                return {contractOwner: ethers_owner.toLowerCase()}})

            const ethers_matchCountMessage = await administrativeSidechainContract.matchCount()
            setMatchCount(() => {
                return {matchCount: ethers_matchCountMessage,}})
        }
        updateUI()
        //here is the loader simulation
        setLoading(true);
        setTimeout(() => {
            setLoading(false);
        }, 7000);

    }, [])

    return (
        <>
            {loading ?
                <div className="loader-container"></div> :
                <div className="decks-container"></div>}
        </>
    )

From my testing it seems that the loader just increases the page loading time by whichever amount of setTimeout that I set.

How do make I make data loading time and setTimeout times overlap rather than go on top of each other?

Thanks for your time in advance!

1 Answers

I think you don't need setTimeout for this. Instead, you can do something like this:

  • Set the loader state to true before updateUI is called
  • Set the loader state to false, when you feel that your task is done

Following is an example:

useEffect(() => {
    const res = [];
    async function updateUI() {
        await Promise.all([
            administrativeSidechainContract.owner(),
            administrativeSidechainContract.matchCount()
        ])
        .then(results => {
          res.push(results)
        });
        const ethers_owner = res[0];
        const ethers_matchCountMessage = res[1];
        // you may set loader to false here
        setLoading(false);
        setContractOwner(() => {
            return {contractOwner: ethers_owner.toLowerCase()}})
         
        setMatchCount(() => {
            return {matchCount: ethers_matchCountMessage,}})
    }

    setLoading(true);
    await updateUI();
    // If you don't want to setLoading(false) inside updateUI method, you may set loader to false here
}, [])
Related