Search code examples
javascriptcontenteditablereactjs

Updating content in contenteditable container with React


I want to break the text the user inputs into the content editable container and replace the content of the container with the same text wrapped in <span> elements.

Here's my render method:

render: function() {
    var children = [],
        index = 0;

    this.state.tokens.forEach(function(token) {
        children.push(<span key={index++}>{token}</span>, <span key={index++}> </span>);
    });

    return <div 
        ref="input"
        className="input" 
        contentEditable="true" 
        onKeyPress={this.keyPress}
    >{children}</div>;
}

(entire example in JSFiddle)

What happens is that after the interval (600ms) from user input, when the state changes and the component is rendered, the children are added but React for some reason adds the original text that was in the container, so it kind of duplicates the text.

Another things is that if then the user selects text and deletes it, in the next update React will throw all kind of errors such as:

Uncaught TypeError: Cannot read property 'parentNode' of undefined

and

Uncaught Error: Invariant Violation: findComponentRoot(..., .0.$2): Unable to find element. This probably means the DOM was unexpectedly mutated (e.g., by the browser), usually due to forgetting a when using tables or nesting

or tag......

Any ideas of why this happens?
Thanks


Solution

  • Unfortunately contenteditable doesn't work properly with React-generated children right now: Uncaught Error when using ContentEditable="true" within Chrome.

    One current workaround is to build the HTML yourself or use React.renderToStaticMarkup and use React's dangerouslySetInnerHTML, though you lose some of React's benefits by doing so.