How do you reload an iframe with ReactJS?
Asked Answered
B

7

24

My ReactJS component contains an iframe. In response to an event in the outer page, I need to reload the iframe. If the user has navigated to another page in the iframe, I need to reset it to the URL that it had when I first loaded the page. This URL is available in this.props.

I've tried using forceUpdate(). I can see that this causes the render method to run, but the iframe doesn't get reset - presumably because React can't tell that anything has changed.

At the moment I'm appending some random text to the iframe's querystring: this URL change forces React to re-render the iframe. However this feels a bit dirty: the page within the iframe is beyond my control so who knows what this extra querystring value might do?

resetIframe() {
    console.log("==== resetIframe ====");
    this.forceUpdate();
}

public render() {
    console.log("==== render ====");

    // How can I use just this.props.myUrl, without the Math.random()?
    let iframeUrl = this.props.myUrl + '&random=' + Math.random().toString();

    return <div>
        <button onClick={() => { this.resetIframe(); }}>Reset</button>
        <iframe src={iframeUrl}></iframe>
    </div>
}

(I'm using TypeScript too, if that makes a difference.)

Bagging answered 16/2, 2018 at 15:48 Comment(0)
D
37

I'd create a state variable with the random, and just update it on resetIframe:

state = {
     random: 0
}
resetIframe() {
    this.setState({random: this.state.random + 1});
}

public render() {
    return <div>
        <button onClick={() => { this.resetIframe(); }}>Reset</button>
        <iframe key={this.state.random} src={this.props.myUrl}></iframe>
    </div>
}

Here is a fiddle working: https://codesandbox.io/s/pp3n7wnzvx

Dworman answered 16/2, 2018 at 16:0 Comment(4)
You're still appending things to the URL though - that's the part I want to avoid. What I really want is <iframe src={this.props.myUrl}>Bagging
Take a look at my answer. I think if you combine both it will work the way you want.Verisimilar
Reading around, people seem to frown upon using key in this way, saying it's not a pure way of using React. However their solution is to call forceUpdate() instead, which doesn't work; changing the value of key does work, so I'm gonna go with that. Thanks! :)Bagging
This works as intended. However the iframe flikers when reloaded. Is there any workaround?Hydr
E
4

In case of Javascript frameworks and technologies, If you update the key, then it'll automatically reload the iFrame. So you just want to increase (or Random number) the value of key for your action.

state = {
    iframe_key: 0,
    iframe_url: 'https://www.google.com/maps' //Your URL here
}
iframeRefresh() {
    this.setState({iframe_key: this.state.iframe_key + 1});
}

public render() {
    return (
        <div>
            <button onClick={() => { this.iframeRefresh(); }}>Reload Iframe</button>
            <iframe key={this.state.iframe_key} src={this.state.iframe_url}> 
            </iframe>
        </div>
    );
}
Emolument answered 4/10, 2021 at 11:10 Comment(1)
excellent :) thnk yuResistant
E
2

Updating the source causes a reload without causing a rerender.

import React, { useState, useRef } from 'react'

function renderIframe({src}){
    const iframeRef = useRef()
    return <>
               <iframe ref={iframeRef} src={src} >
               <span onClick={e => (iframeRef.current.src += '')}>Reload</span
           </>
}
                            
Eudemonics answered 9/8, 2022 at 16:59 Comment(0)
L
1
    <iframe key={props.location.key} />

use This "Router location Key" each click will get random value, whenever to navigate to here this value will get change then iframe will get the refresh

Livestock answered 14/2, 2022 at 7:28 Comment(0)
V
0

You could create a new component which just loads you iframe. In your main component you load it and give it a update prop which you ignore in you iframe component. If you set the prop with a state variable, your component will reload. You can take a look at Diogo Sgrillo's answer for the setState method.

You could also check with shouldcomponentupdate() if the prop changed and only update if it changed.

Verisimilar answered 16/2, 2018 at 16:7 Comment(0)
B
0

Maybe a bit late here :) Just a side note: When you update state based on previous state you should pass a function to setState:

resetIframe() {
    this.setState(prevState => {random: prevState.random + 1});
}
Boche answered 16/9, 2021 at 21:26 Comment(0)
P
0

I think this is the more simple way:

const resetIframes = () => {
  const iframes = document.querySelectorAll("iframe");
  iframes.forEach((iframe) => {
    iframe.src = iframe.src;
});
};
Purapurblind answered 21/5 at 8:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.