Change:
reported the following issue on IRC: (Both on master and 4.0) The repro case is: 1) Render 2) Render 3) Render the same as 1) The div has its innerHTML empty instead of . I don't really know what's going on. can you guys look at it?
One other tidbit: this only seems to happen when the value is exactly the same in step 3 as it was in step 1. If it's different (i.e. ), things work as expected.
What happens if you change step 2 to a instead of a ? It works, right?
I just reduced the test case to 19 lines.
yeah changing 2) to use a span works as expected
If anyone wants to look into this, the bug is probably here
I cannot reproduce what you are seeing: It also bugs if I use a different string
I'm not able to reproduce that particular behavior given this small repro case. The original code had several more layers... will keep trying.
I know this is a very old issue but I had a similar problem and came across this. I found that this problem occurs when you do not add a property to the React component containing the property. So, does not seem to work reproducibly, whereas seems to. I think this could be related to React's diffing algorithm that might not properly treat a component with a statement if that component gets rerendered multiple times with different inner content. Just posting this here in case other people have the same issue and stumble upon this.
thx you saved my day :-)
Seems like the issue is back again. Thanks, solves the problem for me too.
If any of you can post a simple repro case showing the broken behavior here, I'd be happy to take a look at fixing it.
Took me a while to repro, but here you go: (ugly, but demonstrates the issue well)
Thanks. This is the same issue as . No fix currently, but using the key as a workaround is fine and I'll see if we can fix this sometime.
Thanks that was giving me fits!
If anyone is still seeing issues on 0.14, please make a new issue with a simple repro case.
I have this issue, but can't reproduce in a simple example - my original code is layered and I think that's the reason the real DOM doesn't reconcile. In the react debugger is looks as dangerouslySetInnerHTML has proper __html value, but it doesn't equeal to the innerHTML of the actual element. I used an extremely simple (and equally nasty) workaround. Writing it here just in case it will help someone:
Reading out will rarely give you what you put in because the browser does various kinds of normalization on it. If you can repro with a standalone example though I'm happy to take a look.
well, that's more like a control shot :-)
Looks like the issue still exist in 16.4.1 when using on a tag, you cannot nest other or . issue is fixed by replacing the container with a
If you experience something similar three years later, and the original issue is closed, you can be sure it's a different unrelated issue. :-) Please file a new one. We don't keep track of closed issues so your feedback is unfortunately going into the void. When filing a new issue, please provide a reproducing example. when using dangerouslySetInnerHTML on a tag, you cannot nest other or This sounds like browsers work. You can't nest into . This is why React warns when you do it (except in which case React can't validate it).

Discussion:
*/ var textContentAccessor = getTextContentAccessor() || 'NA'; <ins> var LEADING_SPACE = /^ /; </ins> /** * Operations used to process updates to DOM nodes. This is made injectable via * `ReactComponent.DOMIDOperations`.

}, /** <del> * Updates a DOM node's innerHTML set by `props.dangerouslySetInnerHTML`. </del> <ins> * Updates a DOM node's innerHTML. </ins> * * @param {string} id ID of the node to update. <del> * @param {object} html An HTML object with the `__html` property. </del> <ins> * @param {string} html An HTML string. </ins> * @internal */ updateInnerHTMLByID: function(id, html) { var node = ReactMount.getNode(id); // HACK: IE8- normalize whitespace in innerHTML, removing leading spaces. // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html <del> node.innerHTML = (html && html.__html || '').replace(/^ /g, '&nbsp;'); </del> <ins> node.innerHTML = html.replace(LEADING_SPACE, '&nbsp;'); </ins> }, /**

// For quickly matching children type, to test if can be treated as content. var CONTENT_TYPES = {'string': true, 'number': true}; <del> var DANGEROUSLY_SET_INNER_HTML = keyOf({dangerouslySetInnerHTML: null}); </del> var STYLE = keyOf({style: null}); /**

styleUpdates[styleName] = ''; } } <del> } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { // http://jsperf.com/emptying-speed ReactComponent.DOMIDOperations.updateTextContentByID( this._rootNodeID, '' ); </del> } else if (registrationNames[propKey]) { deleteListener(this._rootNodeID, propKey); <del> } else { </del> <ins> } else if ( DOMProperty.isStandardName[propKey] || DOMProperty.isCustomAttribute(propKey)) { </ins> ReactComponent.DOMIDOperations.deletePropertyByID( this._rootNodeID, propKey

// Relies on `updateStylesByID` not mutating `styleUpdates`. styleUpdates = nextProp; } <del> } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { var lastHtml = lastProp && lastProp.__html; var nextHtml = nextProp && nextProp.__html; if (lastHtml !== nextHtml) { ReactComponent.DOMIDOperations.updateInnerHTMLByID( this._rootNodeID, nextProp ); } </del> } else if (registrationNames[propKey]) { putListener(this._rootNodeID, propKey, nextProp); } else if (

_updateDOMChildren: function(lastProps, transaction) { var nextProps = this.props; <del> var lastUsedContent = </del> <ins> var lastContent = </ins> CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null; <del> var contentToUse = </del> <ins> var nextContent = </ins> CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null; <ins> var lastHtml = lastProps.dangerouslySetInnerHTML && lastProps.dangerouslySetInnerHTML.__html; var nextHtml = nextProps.dangerouslySetInnerHTML && nextProps.dangerouslySetInnerHTML.__html; </ins> // Note the use of `!=` which checks for null or undefined. <ins> var lastChildren = lastContent != null ? null : lastProps.children; var nextChildren = nextContent != null ? null : nextProps.children; </ins> <del> var lastUsedChildren = lastUsedContent != null ? null : lastProps.children; var childrenToUse = contentToUse != null ? null : nextProps.children; </del> <ins> // If we're switching from children to content/html or vice versa, remove // the old content var lastHasContentOrHtml = lastContent != null || lastHtml != null; var nextHasContentOrHtml = nextContent != null || nextHtml != null; if (lastChildren != null && nextChildren == null) { this.updateChildren(null, transaction); } else if (lastHasContentOrHtml && !nextHasContentOrHtml) { this.updateTextContent(''); } </ins> <del> if (contentToUse != null) { var childrenRemoved = lastUsedChildren != null && childrenToUse == null; if (childrenRemoved) { this.updateChildren(null, transaction); } if (lastUsedContent !== contentToUse) { this.updateTextContent('' + contentToUse); </del> <ins> if (nextContent != null) { if (lastContent !== nextContent) { this.updateTextContent('' + nextContent); </ins> } <del> } else { var contentRemoved = lastUsedContent != null && contentToUse == null; if (contentRemoved) { this.updateTextContent(''); </del> <ins> } else if (nextHtml != null) { if (lastHtml !== nextHtml) { ReactComponent.DOMIDOperations.updateInnerHTMLByID( this._rootNodeID, nextHtml ); </ins> } <del> this.updateChildren(flattenChildren(nextProps.children), transaction); </del> <ins> } else if (nextChildren != null) { this.updateChildren(flattenChildren(nextChildren), transaction); </ins> } },

ReactDOMIDOperations.updateInnerHTMLByID( 'testID', <del> {__html: ' testContent'} </del> <ins> ' testContent' </ins> ); expect(

it("should empty element when removing innerHTML", function() { var stub = ReactTestUtils.renderIntoDocument( <del> <div dangerouslySetInnerHTML={{__html: ":)"}} /> </del> <ins> <div dangerouslySetInnerHTML={{__html: ':)'}} /> </ins> ); expect(stub.getDOMNode().innerHTML).toEqual(':)');

expect(stub.getDOMNode().innerHTML).toEqual(''); }); <ins> it("should transition from string content to innerHTML", function() { var stub = ReactTestUtils.renderIntoDocument( <div>hello</div> ); expect(stub.getDOMNode().innerHTML).toEqual('hello'); stub.receiveProps( {dangerouslySetInnerHTML: {__html: 'goodbye'}}, transaction ); expect(stub.getDOMNode().innerHTML).toEqual('goodbye'); }); it("should transition from innerHTML to string content", function() { var stub = ReactTestUtils.renderIntoDocument( <div dangerouslySetInnerHTML={{__html: 'bonjour'}} /> ); expect(stub.getDOMNode().innerHTML).toEqual('bonjour'); stub.receiveProps({children: 'adieu'}, transaction); expect(stub.getDOMNode().innerHTML).toEqual('adieu'); }); </ins> it("should not incur unnecessary DOM mutations", function() { var stub = ReactTestUtils.renderIntoDocument(<div value="" />);