@@ -38,6 +38,7 @@ import {
38
38
enableFundamentalAPI ,
39
39
enableSuspenseCallback ,
40
40
enableScopeAPI ,
41
+ enableDoubleInvokingEffects ,
41
42
} from 'shared/ReactFeatureFlags' ;
42
43
import {
43
44
FunctionComponent ,
@@ -71,6 +72,7 @@ import {
71
72
Placement ,
72
73
Snapshot ,
73
74
Update ,
75
+ Passive ,
74
76
} from './ReactSideEffectTags' ;
75
77
import getComponentName from 'shared/getComponentName' ;
76
78
import invariant from 'shared/invariant' ;
@@ -132,6 +134,7 @@ import {
132
134
import { didWarnAboutReassigningProps } from './ReactFiberBeginWork.new' ;
133
135
import {
134
136
NoEffect as NoSubtreeTag ,
137
+ Layout as LayoutSubtreeTag ,
135
138
Passive as PassiveSubtreeTag ,
136
139
} from './ReactSubtreeTags' ;
137
140
@@ -162,7 +165,7 @@ const callComponentWillUnmountWithTimer = function(current, instance) {
162
165
} ;
163
166
164
167
// Capture errors so they don't interrupt unmounting.
165
- function safelyCallComponentWillUnmount ( current , instance ) {
168
+ export function safelyCallComponentWillUnmount ( current : Fiber , instance : any ) {
166
169
if ( __DEV__ ) {
167
170
invokeGuardedCallback (
168
171
null ,
@@ -1868,6 +1871,212 @@ function commitPassiveLifeCycles(finishedWork: Fiber): void {
1868
1871
}
1869
1872
}
1870
1873
1874
+ function commitDoubleInvokeEffectsInDEV (
1875
+ fiber : Fiber ,
1876
+ hasPassiveEffects : boolean ,
1877
+ ) {
1878
+ if ( enableDoubleInvokingEffects ) {
1879
+ if ( __DEV__ ) {
1880
+ invokeLayoutEffectsUnmountInDEV ( fiber ) ;
1881
+ if ( hasPassiveEffects ) {
1882
+ invokePassiveEffectsUnmountInDEV ( fiber ) ;
1883
+ }
1884
+
1885
+ invokeLayoutEffectsMountInDEV ( fiber ) ;
1886
+ if ( hasPassiveEffects ) {
1887
+ invokePassiveEffectsMountInDEV ( fiber ) ;
1888
+ }
1889
+ }
1890
+ }
1891
+ }
1892
+
1893
+ function invokeLayoutEffectsUnmountInDEV ( firstChild ) {
1894
+ if ( enableDoubleInvokingEffects ) {
1895
+ if ( __DEV__ ) {
1896
+ // unmount layout effects
1897
+ let fiber = firstChild ;
1898
+ while ( fiber !== null ) {
1899
+ if ( fiber . child !== null ) {
1900
+ // Should we add a separate subtree tag for this?
1901
+ const primarySubtreeTag = fiber . subtreeTag & LayoutSubtreeTag ;
1902
+ if ( primarySubtreeTag !== NoSubtreeTag ) {
1903
+ invokeLayoutEffectsUnmountInDEV ( fiber . child ) ;
1904
+ }
1905
+ }
1906
+
1907
+ const effectTag = fiber . effectTag ;
1908
+ const current = fiber . alternate ;
1909
+ // This is a mount
1910
+ if ( current === null ) {
1911
+ if ( effectTag & Update ) {
1912
+ switch ( fiber . tag ) {
1913
+ case FunctionComponent :
1914
+ case ForwardRef :
1915
+ case SimpleMemoComponent :
1916
+ case Block : {
1917
+ invokeGuardedCallback (
1918
+ null ,
1919
+ commitHookEffectListUnmount ,
1920
+ null ,
1921
+ HookLayout | HookHasEffect ,
1922
+ fiber ,
1923
+ ) ;
1924
+ if ( hasCaughtError ( ) ) {
1925
+ const unmountError = clearCaughtError ( ) ;
1926
+ captureCommitPhaseError ( fiber , unmountError ) ;
1927
+ }
1928
+ break ;
1929
+ }
1930
+ case ClassComponent : {
1931
+ const instance = fiber . stateNode ;
1932
+ if ( typeof instance . componentWillUnmount === 'function' ) {
1933
+ safelyCallComponentWillUnmount ( fiber , instance ) ;
1934
+ }
1935
+ break ;
1936
+ }
1937
+ }
1938
+ }
1939
+ }
1940
+ fiber = fiber . sibling ;
1941
+ }
1942
+ }
1943
+ }
1944
+ }
1945
+
1946
+ function invokeLayoutEffectsMountInDEV ( firstChild ) {
1947
+ if ( enableDoubleInvokingEffects ) {
1948
+ // mount layout effects
1949
+ if ( __DEV__ ) {
1950
+ let fiber = firstChild ;
1951
+ while ( fiber !== null ) {
1952
+ if ( fiber . child !== null ) {
1953
+ // Should we add a separate subtree tag for this?
1954
+ const primarySubtreeTag = fiber . subtreeTag & LayoutSubtreeTag ;
1955
+ if ( primarySubtreeTag !== NoSubtreeTag ) {
1956
+ invokeLayoutEffectsMountInDEV ( fiber . child ) ;
1957
+ }
1958
+ }
1959
+
1960
+ const effectTag = fiber . effectTag ;
1961
+ const current = fiber . alternate ;
1962
+ if ( current === null ) {
1963
+ if ( effectTag & Update ) {
1964
+ switch ( fiber . tag ) {
1965
+ case FunctionComponent :
1966
+ case ForwardRef :
1967
+ case SimpleMemoComponent :
1968
+ case Block : {
1969
+ invokeGuardedCallback (
1970
+ null ,
1971
+ commitHookEffectListMount ,
1972
+ null ,
1973
+ HookLayout | HookHasEffect ,
1974
+ fiber ,
1975
+ ) ;
1976
+ if ( hasCaughtError ( ) ) {
1977
+ const mountError = clearCaughtError ( ) ;
1978
+ captureCommitPhaseError ( fiber , mountError ) ;
1979
+ }
1980
+ break ;
1981
+ }
1982
+ case ClassComponent : {
1983
+ const instance = fiber . stateNode ;
1984
+ instance . componentDidMount ( ) ;
1985
+ break ;
1986
+ }
1987
+ }
1988
+ }
1989
+ }
1990
+ fiber = fiber . sibling ;
1991
+ }
1992
+ }
1993
+ }
1994
+ }
1995
+
1996
+ function invokePassiveEffectsUnmountInDEV ( firstChild ) : void {
1997
+ if ( enableDoubleInvokingEffects ) {
1998
+ if ( __DEV__ ) {
1999
+ let fiber = firstChild ;
2000
+ while ( fiber !== null ) {
2001
+ if ( fiber . child !== null ) {
2002
+ const primarySubtreeTag = fiber . subtreeTag & PassiveSubtreeTag ;
2003
+ if ( primarySubtreeTag !== NoSubtreeTag ) {
2004
+ invokePassiveEffectsUnmountInDEV ( fiber . child ) ;
2005
+ }
2006
+ }
2007
+
2008
+ const current = fiber . alternate ;
2009
+ if ( current === null ) {
2010
+ switch ( fiber . tag ) {
2011
+ case FunctionComponent :
2012
+ case ForwardRef :
2013
+ case SimpleMemoComponent :
2014
+ case Block : {
2015
+ if ( fiber . effectTag & Passive ) {
2016
+ invokeGuardedCallback (
2017
+ null ,
2018
+ commitHookEffectListUnmount ,
2019
+ null ,
2020
+ HookPassive | HookHasEffect ,
2021
+ fiber ,
2022
+ ) ;
2023
+ if ( hasCaughtError ( ) ) {
2024
+ const unmountError = clearCaughtError ( ) ;
2025
+ captureCommitPhaseError ( fiber , unmountError ) ;
2026
+ }
2027
+ }
2028
+ break ;
2029
+ }
2030
+ }
2031
+ }
2032
+ fiber = fiber . sibling ;
2033
+ }
2034
+ }
2035
+ }
2036
+ }
2037
+
2038
+ function invokePassiveEffectsMountInDEV ( firstChild ) : void {
2039
+ if ( enableDoubleInvokingEffects ) {
2040
+ if ( __DEV__ ) {
2041
+ let fiber = firstChild ;
2042
+ while ( fiber !== null ) {
2043
+ if ( fiber . child !== null ) {
2044
+ const primarySubtreeTag = fiber . subtreeTag & PassiveSubtreeTag ;
2045
+ if ( primarySubtreeTag !== NoSubtreeTag ) {
2046
+ invokePassiveEffectsMountInDEV ( fiber . child ) ;
2047
+ }
2048
+ }
2049
+
2050
+ const current = fiber . alternate ;
2051
+ if ( current === null ) {
2052
+ switch ( fiber . tag ) {
2053
+ case FunctionComponent :
2054
+ case ForwardRef :
2055
+ case SimpleMemoComponent :
2056
+ case Block : {
2057
+ if ( fiber . effectTag & Passive ) {
2058
+ invokeGuardedCallback (
2059
+ null ,
2060
+ commitHookEffectListMount ,
2061
+ null ,
2062
+ HookPassive | HookHasEffect ,
2063
+ fiber ,
2064
+ ) ;
2065
+ if ( hasCaughtError ( ) ) {
2066
+ const mountError = clearCaughtError ( ) ;
2067
+ captureCommitPhaseError ( fiber , mountError ) ;
2068
+ }
2069
+ }
2070
+ break ;
2071
+ }
2072
+ }
2073
+ }
2074
+ fiber = fiber . sibling ;
2075
+ }
2076
+ }
2077
+ }
2078
+ }
2079
+
1871
2080
export {
1872
2081
commitBeforeMutationLifeCycles ,
1873
2082
commitResetTextContent ,
@@ -1880,4 +2089,5 @@ export {
1880
2089
commitPassiveUnmount ,
1881
2090
commitPassiveWork ,
1882
2091
commitPassiveLifeCycles ,
2092
+ commitDoubleInvokeEffectsInDEV ,
1883
2093
} ;
0 commit comments