reactjsinnerhtmlcontenteditablerefs

getting innerHTML from a div after changes through contentEditable in React


thanks for taking the time to look at this.

I am struggling to find out how to make this work specifically in react.

I have used contentEditable to get the div element to be editable and then i have used Refs to make the div reference its innerHTML. But the information does not seem to be put into the state of body.

The ultimate aim is to have it saved in a database, and then loaded to replace the div.

code:

import React, {useState, useRef} from "react";
import "./styles.css";

export default function App() {

let  myRef= useRef()
  const [body, setBody] = useState("");

  let click = () => {
    setBody(myRef.innerHTML)
  }


  return (
    <div className="App">
      <h1 ref={myRef}>Hello CodeSandbox</h1>
      <div></div>
      <h1 contentEditable={true}> rewrite me!</h1>
      <button onClick={click}> CLICK!</button>
    <h1>{body}</h1>

    </div>
  );
}

sandbox

https://codesandbox.io/s/wispy-glitter-nfym4?file=/src/App.js


Solution

  • Access the innerHTML using myRef.current.innerHTML.

    From the docs

    When a ref is passed to an element in render, a reference to the node becomes accessible at the current attribute of the ref.

    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    
    <div id="root"></div>    
    <script type="text/babel">
    function App() {
      let myRef = React.useRef();
      const [body, setBody] = React.useState("");
    
      let click = () => {
        setBody(myRef.current.innerHTML);
      };
    
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <div></div>
    
          {/* I think you misassigned your `myRef`, shouldn't it be on this h1? */}
          {/* suppressContentEditableWarning=true, to suppress warning */}
          <h1 ref={myRef} contentEditable={true} suppressContentEditableWarning={true}> rewrite me!</h1>
    
          <button onClick={click}> CLICK!</button>
          <h1>{body}</h1>
        </div>
      );
    }
    
    ReactDOM.render(<App />, document.getElementById("root"));
    </script>