Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 775
Nitzan Tomer Avatar asked Nov 23 '25 10:11

Nitzan Tomer


1 Answers

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.

like image 154
Sophie Alpert Avatar answered Nov 25 '25 01:11

Sophie Alpert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!