Reconciliation with children and innerHTML across updates
Zolmeister opened this issue · comments
Source
edit: https://codesandbox.io/s/naughty-lamport-565bc
setValue = null
Root = ->
[value, setValue] = useState true
if value
h 'div', {}, [undefined]
else
h 'div',
innerHTML: 'x'
render Root, document.createElement 'div'
window.requestAnimationFrame ->
setValue false
window.requestAnimationFrame ->
setValue true
window.requestAnimationFrame ->
setValue false
Received
Exception: NotFoundError: Failed to execute 'removeChild' on 'Node'
This is expected: innerHTML
is an explicit contract that takes control over what children are rendered outside of the nominal render process.
Can you elaborate as to why it cannot/is not treated like any other property?
Note that React handles this situation correctly.
It is treated like every other property but because innerHTML
is a destructive operative, it is equivalent to if you document.querySelector('div').innerHTML = 'html'
from outside, so when you switch between the two you end up with a clash of both worlds outside of Dyo adding an explicit edge case to handle this.
I think React does this by first rending this to an empty div
i.e document.createElement('div').innerHTML = 'html'
then traversing that div and adding each individual item to the react element, though this no longer seems to be the case so i wonder if it still handles this situation, do you have a react codesandbox for this?
dio 8 originally had this issue as well, but it was resolved - #28 (comment)
latest React works:
https://codesandbox.io/s/naughty-lamport-565bc
Edit: note that replacing
h("div", {}, [undefined])
with h("div", [undefined])
seems to work fine