How to make a loading screen for an iframe using functional components in React

This article already exists! Well.. almost. It's a recurring annoyance of mine, to find tutorials explaining just what I want, only to find class-based React code instead of the more modern functional components.

So lets get to business:

Vanilla HTML elements in React with JSX are more powerful than their framework-less counterparts. Here, we can use the mighty onLoad prop in an iframe:

<iframe
    src="https://dev.to/"
    onLoad={/* some function here */}
/>

When I was searching for this, that's all I would have needed to solve my problem! I had this inhibition that prevented me from trying the obvious; I thought that there was no way an iframe could have an onload event. I should have just tried it anyway! Well, I did... but not before wasting my own time trying to find a workaround I never needed.

Next we are reminded that ternary expressions work in jsx! How convenient 😌

{ loading ? <MyLoadingAnimation /> : <></> }

Remember that the cryptic looking <></> is just jsx's way of saying null, or from a UI perspective, showing nothing.

So, when loading is true, we'll see the loading animation. Otherwise we'll see nothing from that bit of code.

The last member of our party today is the useState hook:

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

Here we initialize loading to true, because when we start out the iframe is not loaded yet.

And its clear now what that onLoad prop should actually do!

<iframe
    src="https://dev.to/"
    onLoad={() => setLoading(false)}
/>

Finally, we bring it all together, using whatever kind of loading screen or animation you want, represented here simply as the a component called MyLoadingAnimation

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

return (
    <>
        { loading ? <MyLoadingAnimation /> : <></> }
        <iframe
            src="https://dev.to/"
            onLoad={() => setLoading(false)}
        />
    </>
)

It's probably a good idea to style MyLoadingAnimation to have position: absolute, to prevent the iframe from moving around when it finishes loading.

<MyLoadingAnimation
    style={{
        position: "absolute"
    }}
/>

It's probably also a good idea to style MyLoadingAnimation to be in the center of whatever space your iframe takes up, but thats a design choice!

Hope this was useful ✌️

22