React: dangerouslySetInnerHTML Bug

Created on 28 Jul 2017  Â·  6Comments  Â·  Source: facebook/react

Hi guys, I found bug https://codesandbox.io/s/1jR21m1BZ

When I copied and pasted image in custom "textarea", I got difference between this.state.text and innerHTML values - it's not correct, and I don't know how to fix it

I reproduce it on Chrome Version 59.0.3071.86 (Official Build) (64-bit), Ubuntu 16.04 LTS

Most helpful comment

I don’t quite understand what behavior you expected, and why.

If you directly modify contentEditable, you shouldn’t expect that it will automatically update the state. state is the source of truth in your example, so on next edit will revert the changes you made by pasting.

As a solution you can either leave contentEditable fully uncontrolled, and not attempt to manage it via React and dangerouslySetInnerHTML, or you can use something like Draft.js for a controlled rich text editor.

All 6 comments

I fix it via

handleChange(e) {
...
  if (this.node) {
    while (this.node.children.length !== 0) {
      this.node.removeChild(this.node.children[0]);
    }
    this.node.innerHtml = text
  }
...
}

https://codesandbox.io/s/mjGvEJpp

I don’t quite understand what behavior you expected, and why.

If you directly modify contentEditable, you shouldn’t expect that it will automatically update the state. state is the source of truth in your example, so on next edit will revert the changes you made by pasting.

As a solution you can either leave contentEditable fully uncontrolled, and not attempt to manage it via React and dangerouslySetInnerHTML, or you can use something like Draft.js for a controlled rich text editor.

@gaearon Draft.js is great solution, but chrome plugin Grammarly don't work with it https://github.com/facebook/draft-js/issues/616

I develop chat with support. And support team use Grammarly plugin. So I need make custom rich textarea with emoji, which work with grammarly

Fair enough. Just saying that in this case “controlled” approach won’t work for you. Just render an empty <div contentEditable /> with React and then manage it from lifecycle hooks.

@gaearon thank you for idea, but how to remove HTML Entities when user will paste text from buffer?

I don’t know, sorry. This doesn’t sound React-specific to me. I would suggest checking for articles or examples of working with contentEditable and sanitizing it.

Was this page helpful?
0 / 5 - 0 ratings