React warns:
A component is
contentEditable
and containschildren
managed by
React. It is now your responsibility to guarantee that none of
those nodes are unexpectedly modified or duplicated. This is
probably not intentional.
I am writing a rich text editor using React, and have written it to ensure that the nodes are not modified by the browser by capturing all input events, performing the modifications on my internal document format, and re-rendering using React. However, on each render, React still warns me about this.
I would be awesome to be able to disable this warning somehow, such as with a specific value to the contentEditable prop, another name or something. I'm not sure the best approach to take here, so I thought I'd create an issue for discussion around this.
+1
Duplicate of https://github.com/facebook/react/issues/4662. The warning is useful in most cases. I'm pretty sure you get a paste event for nodes that are not contentEditable, so if you are capturing all the events and preventing the browser changes, why do you have contentEditable
specified?
To avoid the warning, you can bail out of React (https://github.com/facebook/react/issues/2477#issuecomment-173315553) and then call React.render() in your contentEditable container node, which will not cause us to warn (afaik).
It needs to be contentEditable in order to enable the browser cursor behavior, input events, etc. If you render at a different mount point, preventing events from bubbling up to parent components no longer works correctly (see #1691).
As a stopgap solution I ended up overriding console.error
in my app and ignoring messages that match a regex. Pretty silly, but it works for now, and of course it's not enabled in production anyway. I'd definitely love to have an option on the component to say "hey react, I know what I'm doing" though.
You can capture input events without content editable (http://jsfiddle.net/vm9gjhs3/) and can simulate the cursor behavior yourself (which you basically need to do anyway in order to implement a good editor, as per https://medium.com/medium-eng/why-contenteditable-is-terrible-122d8a40e480#6497). The browsers all have different behaviors with regards to how cursor position works. If you want a truly nice editor, you will end up using almost nothing from contentEditable. But I get it, you're trying to reuse the browser's functionality under the (very optimistic) assumption that contentEditable gets you most of the way there.
With regards to your hack: A better stopgap solution (hack) would probably be to set contentEditable imperatively (as demonstrated in my fiddle: http://jsfiddle.net/4q2p6ug8/). That way, React doesn't even know you've set it, and you can share your component without overwriting other people's console.error
method.
Yeah, that's the google docs method: reimplement everything. However for non-word processors, it is possible to get most of the way there using content editable and some code to manage the selection. Even medium and the new Facebook notes (made with react) still use content editable to some degree.
I like that new hack. Much better. Thanks.
@jimfb @spicyj this seems like something I could take a look at!
Have there been any (internal) discussion what such an opt-out would look like? I could imagine it being it's own function exposed through React
(similar to React.initializeTouchEvents(true)
back in the day).
React.disableContentEditableWarning(true);
or another property specified on the component itself (could make it a bit hard to work with on purpose, similar to dangerouslySetInnerHTML
)
<MyComponent contentEditable disableContentEditableWarning />
The benefit, and also drawback, of the first option is that it'd be app-wide, whereas the second one would have to be specified on every contentEditable
component.
We generally avoid global configuration like the plague, so we would almost certainly prefer that it be specified on the component itself. At first glance, I kind of like your second proposal. I'll bikeshed a little with Ben and see what we come up with.
My two best naming proposals right now are silenceContentEditableWarning
and allowContentEditableChildren
, both of which I like a little more than disableContentEditableWarning
.
How about dangerouslyAllowContentEditableChildren
? Mirrors dangerouslySetInnerHTML
.
I like "suppress" better than "silence". Or "allow" is also fine, but the problem with allowContentEditableChildren
is that it implies a possible change in behavior, rather than merely disabling the warning.
For this reason, I think I'm in favor of suppressContentEditableWarning
or contentEditableWarning="disabled"
Should we document this in the content editable doc?
If you want to send a PR, sure.
Most helpful comment
+1