DEV Community

Andy Chamberlain
Andy Chamberlain

Posted on • Edited on

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 */}
/>
Enter fullscreen mode Exit fullscreen mode

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 /> : <></> }
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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)}
/>
Enter fullscreen mode Exit fullscreen mode

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)}
        />
    </>
)
Enter fullscreen mode Exit fullscreen mode

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"
    }}
/>
Enter fullscreen mode Exit fullscreen mode

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 ✌️

Top comments (1)

Collapse
 
suzandev profile image
Sujan Tamang

I reached the same code as above but the problem was my content got loaded first and was visible to ui, then only images were loaded which triggered onLoad. so, loading state was still showing when the content is loaded because images were still loading.