Invoking function defined within iframe from parent using React Ref

1.6k Views Asked by At

I have an iframe within my React code that I'm trying to call from parent. I created a React Ref to the iframe that is connected to the iframe, but I'm not sure how to react the functions within the iframe from the React component. Here is a simplified example:

// App.tsx
import * as React from "react";
import "./styles.css";

interface Props {}

interface State {
  iframeRef: React.RefObject<HTMLIFrameElement>;
}

export default class App extends React.Component<Props, State> {

  /**
   * @inheritdoc
   */
  public constructor(props: Props) {
    super(props);
    this.state = {
        ...this.state,
        iframeRef: React.createRef()
    };
  }
  
  /**
   * @inheritdoc
   */
  public render() { 
    return (
    <div className="App">
      <h1>In component</h1>
      <iframe
        ref={this.state.iframeRef}
        title={"iframe"}
        src={"public/iframe.html"}
      />
    <button 
      onClick={() => this.state.iframeRef.current!.contentWindow!.document!.body!.sayHi()}
    >click me</button>
    </div>
  );
    }
}

and here is the HTML code that is called in the iframe:

// public/iframe.html
<!DOCTYPE html>
<html>
  <body>
    in iframe
    <script>
      function sayHi() {
        alert("hello");
      }
    </script>
  </body>
</html>

I have two problems. I am unable to see the HTML defined in the src file, it's just an empty box with a border. The other problem is when I click the button, I get the error _this2.state.iframeRef.current.contentWindow.document.body.sayHi is not a function which makes sense because I'm not sure how to reference the function that is defined within the iframe src file.

How can I make the iframe show the contents of the src file? And how can I access the functions defined in the iframe that I am referencing?

I have this sandbox that I've been playing with

1

There are 1 best solutions below

0
On

I figured this out on my own. The problem was a bit unrelated to what I expected, but I'll post in case anyone else runs into this issue. Putting public/iframe.html was causing it to not find the file, and I needed to set src={iframe.html} and didn't realize public was the default location to search for these files. Also, calling the function that is within the html should be onClick={() => this.state.iframeRef.current!.contentWindow!.sayHi()}.