I have code that depends on the mount order to be the same as the render order. I noticed that in 10.x, this is no longer the case.
Here's a little snippet to demonstrate the difference:
class Item extends Component {
componentDidMount() {
console.log('mount', this.props.index)
}
render() {
console.log('render', this.props.index)
return <h1>{this.props.index}</h1>
}
}
const App = () => {
return <div>
<Item index={0} />
<Item index={1} />
<Item index={2} />
</div>
}
Preact 8.x logs as expected
render 0
render 1
render 2
mount 0
mount 1
mount 2
However with 10.x (beta.3 as of writing this), you get the following output:
render 0
render 1
render 2
mount 2
mount 1
mount 0
Do you consider this a bug?
I can confirm this is happening, this is caused by the following line: https://github.com/preactjs/preact/blob/master/src/diff/index.js#L164
We pop the array of mounts so that inner components trigger a didMount before their parents. With an array of children of the same depth this however makes for some unexpected behavior. I'm going to look deeper into this.
I believe this is also behind issues I've had using material-ui.com components. Specifically a select combo box in a dialog opens behind the dialog and the only difference between react and preact is the order of insertion of the elements into the html. Reordering them by swapping their positions in the developer tools in chrome creates the expected outcome. (Incidentally the work around to this specific outcome was to use the native select option with material).
I have the same issue with, intersection-observer & an array of sibling components.
The DOM element refs are added to the observer in componentDidMount
All siblings mounts are processed in
https://github.com/preactjs/preact/blob/master/src/diff/index.js#L165;
however, the mounts are poped, hence processed in the opposite order they were added;
changing to shift() works as expected.
This has the undesired effect of DOM nodes in view being processed bottom right to top left.
Most helpful comment
I can confirm this is happening, this is caused by the following line: https://github.com/preactjs/preact/blob/master/src/diff/index.js#L164
We pop the array of mounts so that inner components trigger a didMount before their parents. With an array of children of the same depth this however makes for some unexpected behavior. I'm going to look deeper into this.