-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fire useEffect in reverse component depth order #3354
Conversation
This changes the ordering of useEffect callbacks so that they fire roughly in order of reverse component depth. Callbacks will still fire in-order for multiple useEffect()'s within a single component, but the callbacks for a child component will fire before those of a parent.
Size Change: +70 B (0%) Total Size: 42.2 kB
ℹ️ View Unchanged
|
@developit I think we're already executing in the right order https://codesandbox.io/s/snowy-wave-jfz5s?file=/src/index.js |
@JoviDeCroock ah, I think I see why - we push into the afterPaintCallback queue from within |
Ah - figured it out: this affects updates when components are memoized or bail out via sCU. I believe this is why only two tests are red from the change - we were already calling inner-to-outer in the majority of cases, this only affects the case where (state-based) updates are scheduled for both a subtree and its (grand)parent. |
… update Reason the tests failed: preactjs/preact#3354
… update Reason the tests failed: preactjs/preact#3354
… update Reason the tests failed: preactjs/preact#3354
… update Reason the tests failed: preactjs/preact#3354
This changes the ordering of useEffect callbacks so that they fire
roughlydeterministically in order of reverse tree depth (innermost to outermost). Callbacks will still fire in-order for multiple useEffect()'s within a single component, but the callbacks for a child component will always fire before those of a parent.We already invoked useEffect() callbacks in reverse-depth-order for normal/full tree updates, since they were pushed into the queue from
options.diffed()
which fires inner-to-outer. With this PR, that ordering of useEffect callbacks is now also used when a parent subtree and child subtree are both enqueued for rendering, and the parent update does not descend to the child/grandchild (due to sCU/memo). In that case, we always render the parent component/tree before the child, but will now fire the child's useEffect callbacks before those of the parent.h/t @wonderful-panda for uncovering this: https://twitter.com/wonderful_panda/status/1467015985672892416
We don't have specific timing that we state these calls will adhere to, so it seems like aligning with React makes the most sense here. React fires in-order within a component, but inner-to-outer between components (demo):