mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Deletion effects should fire parent -> child (#20584)
* Test: Deletion effects should fire parent -> child Regression in new effect implementation * Fix passive deletion effect ordering
This commit is contained in:
@@ -2005,6 +2005,13 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
|
||||
) {
|
||||
while (nextEffect !== null) {
|
||||
const fiber = nextEffect;
|
||||
|
||||
// Deletion effects fire in parent -> child order
|
||||
// TODO: Check if fiber has a PassiveStatic flag
|
||||
setCurrentDebugFiberInDEV(fiber);
|
||||
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber);
|
||||
resetCurrentDebugFiberInDEV();
|
||||
|
||||
const child = fiber.child;
|
||||
// TODO: Only traverse subtree if it has a PassiveStatic flag
|
||||
if (child !== null) {
|
||||
@@ -2023,11 +2030,6 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(
|
||||
) {
|
||||
while (nextEffect !== null) {
|
||||
const fiber = nextEffect;
|
||||
// TODO: Check if fiber has a PassiveStatic flag
|
||||
setCurrentDebugFiberInDEV(fiber);
|
||||
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber);
|
||||
resetCurrentDebugFiberInDEV();
|
||||
|
||||
if (fiber === deletedSubtreeRoot) {
|
||||
nextEffect = null;
|
||||
return;
|
||||
|
||||
@@ -2005,6 +2005,13 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(
|
||||
) {
|
||||
while (nextEffect !== null) {
|
||||
const fiber = nextEffect;
|
||||
|
||||
// Deletion effects fire in parent -> child order
|
||||
// TODO: Check if fiber has a PassiveStatic flag
|
||||
setCurrentDebugFiberInDEV(fiber);
|
||||
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber);
|
||||
resetCurrentDebugFiberInDEV();
|
||||
|
||||
const child = fiber.child;
|
||||
// TODO: Only traverse subtree if it has a PassiveStatic flag
|
||||
if (child !== null) {
|
||||
@@ -2023,11 +2030,6 @@ function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(
|
||||
) {
|
||||
while (nextEffect !== null) {
|
||||
const fiber = nextEffect;
|
||||
// TODO: Check if fiber has a PassiveStatic flag
|
||||
setCurrentDebugFiberInDEV(fiber);
|
||||
commitPassiveUnmountInsideDeletedTreeOnFiber(fiber);
|
||||
resetCurrentDebugFiberInDEV();
|
||||
|
||||
if (fiber === deletedSubtreeRoot) {
|
||||
nextEffect = null;
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
/* eslint-disable no-func-assign */
|
||||
|
||||
'use strict';
|
||||
|
||||
let React;
|
||||
let ReactNoop;
|
||||
let Scheduler;
|
||||
let useEffect;
|
||||
let useLayoutEffect;
|
||||
|
||||
describe('ReactHooksWithNoopRenderer', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
jest.useFakeTimers();
|
||||
|
||||
React = require('react');
|
||||
ReactNoop = require('react-noop-renderer');
|
||||
Scheduler = require('scheduler');
|
||||
useEffect = React.useEffect;
|
||||
useLayoutEffect = React.useLayoutEffect;
|
||||
});
|
||||
|
||||
test('layout unmmouts on deletion are fired in parent -> child order', async () => {
|
||||
const root = ReactNoop.createRoot();
|
||||
|
||||
function Parent() {
|
||||
useLayoutEffect(() => {
|
||||
return () => Scheduler.unstable_yieldValue('Unmount parent');
|
||||
});
|
||||
return <Child />;
|
||||
}
|
||||
|
||||
function Child() {
|
||||
useLayoutEffect(() => {
|
||||
return () => Scheduler.unstable_yieldValue('Unmount child');
|
||||
});
|
||||
return 'Child';
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
root.render(<Parent />);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput('Child');
|
||||
await ReactNoop.act(async () => {
|
||||
root.render(null);
|
||||
});
|
||||
expect(Scheduler).toHaveYielded(['Unmount parent', 'Unmount child']);
|
||||
});
|
||||
|
||||
test('passive unmmouts on deletion are fired in parent -> child order', async () => {
|
||||
const root = ReactNoop.createRoot();
|
||||
|
||||
function Parent() {
|
||||
useEffect(() => {
|
||||
return () => Scheduler.unstable_yieldValue('Unmount parent');
|
||||
});
|
||||
return <Child />;
|
||||
}
|
||||
|
||||
function Child() {
|
||||
useEffect(() => {
|
||||
return () => Scheduler.unstable_yieldValue('Unmount child');
|
||||
});
|
||||
return 'Child';
|
||||
}
|
||||
|
||||
await ReactNoop.act(async () => {
|
||||
root.render(<Parent />);
|
||||
});
|
||||
expect(root).toMatchRenderedOutput('Child');
|
||||
await ReactNoop.act(async () => {
|
||||
root.render(null);
|
||||
});
|
||||
expect(Scheduler).toHaveYielded(['Unmount parent', 'Unmount child']);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user