So I made a component for including content-editable components in my app. I copied it from some gist I believe, then edited to what i needed.
The code is below. When I edit it, it triggers updates on the parent just fine, but when I attempt to set props.html in the parent, it doesn't reflect in the UI. FURTHER, the console.log shows that this.props.html is equal to '' a blank string, yet the UI doesn't update, and maintains the text that was originally in there.
I don't understand how this is possible... dangerouslySetInnerHtml = {__html: ''} should make it so the UI reflects an empty string... it feels like it should be impossible for it to show the old text.
var React = require('react');
var ContentEditable = React.createClass({
render: function(){
//TODO: find where html=undefined and fix it! So I can remove this? Maybe I should keep this safety.
var html = this.props.html || '';
console.log('content editable render, html: ', this.props.html);
return <div id="contenteditable"
onInput={this.emitChange}
onBlur={this.emitChange}
contentEditable
dangerouslySetInnerHTML={{__html: html}}></div>;
},
shouldComponentUpdate: function(nextProps){
return nextProps.html !== this.getDOMNode().innerHTML;
},
emitChange: function(){
var html = this.getDOMNode().innerHTML;
if (this.props.onChange && html !== this.lastHtml) {
this.props.onChange({
target: {
value: html
}
});
}
this.lastHtml = html;
}
});
module.exports = ContentEditable;
(A little background, I'm trying to clear my input after submitting it to be saved. The clearing isn't working, hence this question.)
I got a very similar problem using contentEditable
and shouldComponentUpdate
, it looks like there is a bug when resetting the innerHTML to the same previous value using dangerouslySetInnerHTML
function (or prop) (I think it does not work even if you insert the code without using it) ... I suspect (this is just an idea) that React compares the last value set through dangerouslySetInnerHTML
with the new one you are trying to send and decides not to update the component because it is the same (even if the real innerHtml has changed due to user interactions, because those interactions does not trigger any state or props update on React).
Solution: The easiest solution I found was to use a different key each time I needed it to re-render. for example using key={Date()}
.
Example: Here you can find your code (I changed some of it to make it work), when you type '?' into the div, the text inside the ContentEditable component should become an empty string (i.e. ''), it works only once, the second time you type '?' won't work because the innerHTML for react will be the same to the one you're setting (i.e. an empty string so it won't update the component).
And here, I added the key={Date()}
(this is the easiest way to show you that this work, but it is not the best way to set a unique key each time it re-render) to the editable component, now you can type any number of '?' and it will work.
I found another solution that is probably better than generating random keys. Putting a key specifically on the div that calls #dangerouslySetInnerHtml, and not just on the component itself
<div class='wrapper'>
<div key={this.props.thing.id} dangerouslySetInnerHtml={this.props.thing.content} />
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With