When rendering:
render: function() {
<span contentEditable={this.state.isEditing}>{this.state.value}</span>
}
Output:
<span contenteditable="true" data-reactid=".1msoq843u9s.1.$49.1.0">Hello World</span>
There is only a text node as a child of this span, no react components and yet I still receive the
"A component is contentEditable
and contains children
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."
Is this expected?
Hmm, an interesting special-case, but I'm curious... won't pressing CTRL-B or w/e wrap the selected text in <b>
?
Operating <input>
in controlled mode is made possible by value
being marked as HAS_SIDE_EFFECTS
, which means that for every update it checks the DOM value
and compares it against the current value. This stops the cursor jumping to the end for every key press. But this cannot be realistically applied for contentEditable
as it may become prohibitively expensive.
I'm not the expert on this, but I believe contentEditable
is best handled through manual DOM interaction.
I feel the warning may be preferable regardless, you're free to ignore it if you can guarantee that it is not an issue for you.
cc @salier
Hmm, an interesting special-case, but I'm curious... won't pressing CTRL-B or w/e wrap the selected text in ?
Behavior varies by browser, but yes. Even beyond that, browsers do strange things with text nodes inside contentEditable
, so React can quickly get out of sync with the DOM even with vanilla text editing behavior.
I'm not the expert on this, but I believe
contentEditable
is best handled through manual DOM interaction.
Pretty much.
There's not really a decent compromise for contentEditable
in React. You either need to be completely hands-off and rope it off from React updates, or you need to maintain absolute control over the component (content, selection, etc.) and ignore the warning. The latter option is not for the faint of heart. :)
I can see potential for onChange
support of plaintext-only
editables, but I don't think there's much need for that at this point.
I think I can close this out. As noted there is a child so we warn but if you really know what you're doing then feel free to ignore it.
@zpao No, you can't just ignore it because it's shouting it in your face by outputting an error in the console.
@halt-hammerzeit You can rope it off from React (render an empty tag using React, attach a ref, and add a content-editable child in componentDidMount
).
FWIW, my recommendation is to build (or use) a React component which implements the editable semantics you want. It's unfortunate to be forced to implement what the browsers already have builtin, but you'll have a better end experience in the end, because you'll have an editable component that plays nice with a declarative framework like React. Worth reading: https://medium.com/medium-eng/why-contenteditable-is-terrible-122d8a40e480#.aq2xacp42
@jimfb Oh, thanks, good thoughts, I'll have a read.
@jimfb That post is so confusing... What about DraftJS? drops the same Warning.
this work for me
render: function() {
<span contentEditable={this.state.isEditing}
dangerouslySetInnerHTML={{__html: this.state.value}}
onBlur={(e)=>{
this.setState({
value:e.target.innerHTML
});
}} ></span>
}
Most helpful comment
@zpao No, you can't just ignore it because it's shouting it in your face by outputting an error in the console.