TypeError: no se puede leer la propiedad 'contentWindow' de undefined

Aug 15 2020

Estoy tratando de hacer un editor de texto enriquecido usando React.js y estoy usando iframe con la propiedad designMode establecida en 'ON'. Quiero poner en negrita el texto seleccionado al hacer clic en un botón. Quiero usar la función execCommand() pero sigo recibiendo este error: TypeError: No se puede leer la propiedad 'contentWindow' de undefined. Soy un principiante en React y no puedo descubrir cómo abordar este problema.

He adjuntado mi código para su referencia.

import React, { Component } from 'react'
import 'font-awesome/css/font-awesome.css'


export default class Editor extends Component {

    constructor(){
        super()
        this.execComd = this.execComd.bind(this)
    }

    componentDidMount(){
       let editor = this.textField.contentWindow.document
       editor.designMode = 'on'
    }

    execComd(command){
        this.textField.contentWindow.execCommand(command, false, null)   
    }

    render() {
        return (
            <> 
                <div>
                    <button onClick={this.execComd('bold')}><i className="fa fa-bold"></i></button>
                </div>
                <iframe 
                    ref={textField => this.textField = textField} 
                    id="textField" 
                    name="textField" 
                    style={{width: "1000px",height: "500px"}} 
                    frameborder="1">
                </iframe>
            </>
        )
    }
}

Respuestas

1 Asutosh Aug 15 2020 at 20:51

Tienes que crear una referencia enlazada a esto. Como this.myRef = React.createRef(), dentro del constructor. Luego asigna eso en el método de renderizado.

ref={this.myRef}

Dentro de escCommand puedes tener ahora:

execComd(command){
       this.myRef.current.contentWindow.execCommand(command, false, null)   
    }

Para crear una demostración funcional de mi propuesta, ignórela, ya que eliminé algunos códigos no deseados que desconozco:

import React, { Component } from 'react'


export default class Editor extends Component {

    constructor(){
        super()
        this.execComd = this.execComd.bind(this)
        this.myRef=React.createRef();
    }

    componentDidMount(){
      
    }

    execComd(command){
      console.log("fired");
      console.log(this.myRef.current.contentWindow);
    
    }

    render() {
        return (
            <> 
                <div>
                    <button onClick={()=>this.execComd('bold')}>Click<i className="fa fa-bold"></i></button>
                </div>
                <iframe 
                    ref={this.myRef} 
                    title="hello"
                    id="textField" 
                    name="textField" 
                    style={{width: "1000px",height: "500px"}} 
                    frameborder="1">
                </iframe>
            </>
        )
    }
}