0

I am trying to use react reference to render data into iframe but I am getting

reference.current value null.

I also check the value in componentDidMount() still it give me null value. As I set refrence value in constructor. Reference is set to "PreviewEmailModal" component insted of "iframe" component.

Thats why I am getting current value as null. So some can please help me to set refrence to iframe component.

React version- 16.4.2
React DOM version - 16.4.2
import React from "react";
import PropTypes from 'prop-types'

import { Button, Modal } from "react-bootstrap";

class PreviewEmailModal extends React.Component {

    constructor() {
        super();
this.textInput = React.createRef();
        this.state = {
            desktopPreview: true
        };
    }
    render() {
        this.props;
        debugger
        return (
            <Modal
                show={true} onHide={() => {
                    this.props.closeModal();
                }}
                className="preview-email-modal"
                bsSize="lg">
                <Modal.Header closeButton>
                    <Modal.Title>Preview</Modal.Title>
                </Modal.Header>
                <Modal.Body >
                    <div className="preview-icons">
                        <span className={this.state.desktopPreview ? "active-preview-icon margin-5" : ""}>
                            <i className="glyphicon glyphicon-blackboard" onClick={() => {
                                this.togglePreview();
                            }} />
                        </span>
                        <span className={this.state.desktopPreview ? "" : "active-preview-icon margin-5"}>
                            <i className="glyphicon glyphicon-phone" onClick={() => {
                                this.togglePreview();
                            }} />
                        </span>
                    </div>
                    <div>
                        <div className="text-center">
                            <iframe
                                title={"previewFrame"}
                                style={this.state.desktopPreview ?
                                    { width: "600px", height: "450px" } :
                                    { width: "320px", height: "450px" }}
                                id="previewIframe"
                                ref={(input) => {
                                    this.textInput = input;
                                }}
                            />
                        </div>
                    </div>

                </Modal.Body>
            </Modal>
        );
    }

    componentDidUpdate() {
        debugger
    }

    componentDidMount() {
        const { current } = this.textInput;
         //Here I get current value as null every time
         const { data } = this.props;

         if (current !== null) {
             const doc = current.contentDocument;
            doc.open();
            doc.write(data);
            doc.close();
         }
    }

    focusTextInput() {
        // Explicitly focus the text input using the raw DOM API
        this.textInput.focus();
    }

    togglePreview() {
        this.setState({ desktopPreview: !this.state.desktopPreview });
    }
}

PreviewEmailModal.propTypes = {
    closeModal: PropTypes.func,
    data: PropTypes.string
};

export default PreviewEmailModal;
EzLo
  • 13,780
  • 10
  • 33
  • 38
nikhil
  • 9
  • 2

3 Answers3

1

You are not using Ref correctly. Instead of passing callback to ref field pass instance.

OR pass

ref={this.textInput}

instead of

ref={(input) => {this.textInput = input;}}

tarzen chugh
  • 10,561
  • 4
  • 20
  • 30
0

You're likely trying to reference this.textInput when it's not actually on the DOM.

I solved this by adding componentDidUpdate like this:

componentDidUpdate() {
  const { visible, emailHtml } = this.props;

  if (visible) {
    // this.iframe is my iframe ref
    this.iframe.contentWindow.document.write(emailHtml);
  }
}

On another note I don't think you need this line for the ref to work:

this.textInput = React.createRef();

I had the exact same issue (literally my component is called PreviewEmailModal too). I even have a very similar Modal component I'm using within PreviewEmailModal as well. Small world!

-1

As I don't know all of your code I would recommend to move your code from componentDidMount to the ref callback. Please check the answer of Dan Abramov here (componentDidMount called BEFORE ref callback)

  • Why does anyone downvote this answer without any comment? As every business logic the questioner is defined in componentDidMount there is no problem to move it to the ref callback. Inside the callback you can safely reference the DOM-element. – Sebastian Brockly Jan 15 '20 at 01:44