46
setIsStrictModeForDevtools,
47
} from './ReactFiberDevToolsHook';
48
import {
49
- IndeterminateComponent,
49
FunctionComponent,
50
ClassComponent,
51
HostRoot,
66
SimpleMemoComponent,
67
LazyComponent,
68
IncompleteClassComponent,
69
+ IncompleteFunctionComponent,
70
ScopeComponent,
71
OffscreenComponent,
72
LegacyHiddenComponent,
114
import getComponentNameFromFiber from 'react-reconciler/src/getComponentNameFromFiber';
115
import getComponentNameFromType from 'shared/getComponentNameFromType';
116
import ReactStrictModeWarnings from './ReactStrictModeWarnings';
117
-import {REACT_LAZY_TYPE, getIteratorFn} from 'shared/ReactSymbols';
117
+import {
118
+ REACT_LAZY_TYPE,
119
+ REACT_FORWARD_REF_TYPE,
120
+ REACT_MEMO_TYPE,
121
+ getIteratorFn,
122
+} from 'shared/ReactSymbols';
123
import {
124
getCurrentFiberOwnerNameInDevOrNull,
125
setIsRendering,
247
} from './ReactFiberClassComponent';
248
import {resolveDefaultProps} from './ReactFiberLazyComponent';
249
import {
245
- resolveLazyComponentTag,
250
createFiberFromTypeAndProps,
251
createFiberFromFragment,
252
createFiberFromOffscreen,
253
createWorkInProgress,
254
isSimpleFunctionComponent,
255
+ isFunctionClassComponent,
256
} from './ReactFiber';
257
import {
258
retryDehydratedSuspenseBoundary,
308
let didReceiveUpdate: boolean = false;
309
310
let didWarnAboutBadClass;
306
-let didWarnAboutModulePatternComponent;
311
let didWarnAboutContextTypeOnFunctionComponent;
312
let didWarnAboutGetDerivedStateOnFunctionComponent;
313
let didWarnAboutFunctionRefs;
318
319
if (__DEV__) {
320
didWarnAboutBadClass = ({}: {[string]: boolean});
317
- didWarnAboutModulePatternComponent = ({}: {[string]: boolean});
321
didWarnAboutContextTypeOnFunctionComponent = ({}: {[string]: boolean});
322
didWarnAboutGetDerivedStateOnFunctionComponent = ({}: {[string]: boolean});
323
didWarnAboutFunctionRefs = ({}: {[string]: boolean});
1047
}
1048
}
1049
1050
+function mountIncompleteFunctionComponent(
1051
+ _current: null | Fiber,
1052
+ workInProgress: Fiber,
1053
+ Component: any,
1054
+ nextProps: any,
1055
+ renderLanes: Lanes,
1056
+) {
1057
+ resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
1058
+
1059
+ workInProgress.tag = FunctionComponent;
1060
+
1061
+ return updateFunctionComponent(
1062
+ null,
1063
+ workInProgress,
1064
+ Component,
1065
+ nextProps,
1066
+ renderLanes,
1067
+ );
1068
+}
1069
+
1070
function updateFunctionComponent(
1071
current: null | Fiber,
1072
workInProgress: Fiber,
1074
nextProps: any,
1075
renderLanes: Lanes,
1076
) {
1077
+ if (__DEV__) {
1078
+ if (
1079
+ Component.prototype &&
1080
+ typeof Component.prototype.render === 'function'
1081
+ ) {
1082
+ const componentName = getComponentNameFromType(Component) || 'Unknown';
1083
+
1084
+ if (!didWarnAboutBadClass[componentName]) {
1085
+ console.error(
1086
+ "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
1087
+ 'This is likely to cause errors. Change %s to extend React.Component instead.',
1088
+ componentName,
1089
+ componentName,
1090
+ );
1091
+ didWarnAboutBadClass[componentName] = true;
1092
+ }
1093
+ }
1094
+
1095
+ if (workInProgress.mode & StrictLegacyMode) {
1096
+ ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
1097
+ }
1098
+
1099
+ if (current === null) {
1100
+ // Some validations were previously done in mountIndeterminateComponent however and are now run
1101
+ // in updateFuntionComponent but only on mount
1102
+ validateFunctionComponentInDev(workInProgress, workInProgress.type);
1103
+
1104
+ if (disableLegacyContext && Component.contextTypes) {
1105
+ console.error(
1106
+ '%s uses the legacy contextTypes API which was removed in React 19. ' +
1107
+ 'Use React.createContext() with React.useContext() instead.',
1108
+ getComponentNameFromType(Component) || 'Unknown',
1109
+ );
1110
+ }
1111
+ }
1112
+ }
1113
+
1114
let context;
1115
if (!disableLegacyContext) {
1116
const unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
1757
let Component = init(payload);
1758
// Store the unwrapped component in the type.
1759
workInProgress.type = Component;
1700
- const resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component));
1760
+
1761
const resolvedProps = resolveDefaultProps(Component, props);
1702
- let child;
1703
- switch (resolvedTag) {
1704
- case FunctionComponent: {
1762
+ if (typeof Component === 'function') {
1763
+ if (isFunctionClassComponent(Component)) {
1764
+ workInProgress.tag = ClassComponent;
1765
if (__DEV__) {
1706
- validateFunctionComponentInDev(workInProgress, Component);
1766
workInProgress.type = Component =
1708
- resolveFunctionForHotReloading(Component);
1767
+ resolveClassForHotReloading(Component);
1768
}
1710
- child = updateFunctionComponent(
1769
+ return updateClassComponent(
1770
null,
1771
workInProgress,
1772
Component,
1773
resolvedProps,
1774
renderLanes,
1775
);
1717
- return child;
1718
- }
1719
- case ClassComponent: {
1776
+ } else {
1777
+ workInProgress.tag = FunctionComponent;
1778
if (__DEV__) {
1779
+ validateFunctionComponentInDev(workInProgress, Component);
1780
workInProgress.type = Component =
1722
- resolveClassForHotReloading(Component);
1781
+ resolveFunctionForHotReloading(Component);
1782
}
1724
- child = updateClassComponent(
1783
+ return updateFunctionComponent(
1784
null,
1785
workInProgress,
1786
Component,
1787
resolvedProps,
1788
renderLanes,
1789
);
1731
- return child;
1790
}
1733
- case ForwardRef: {
1791
+ } else if (Component !== undefined && Component !== null) {
1792
+ const $$typeof = Component.$$typeof;
1793
+ if ($$typeof === REACT_FORWARD_REF_TYPE) {
1794
+ workInProgress.tag = ForwardRef;
1795
if (__DEV__) {
1796
workInProgress.type = Component =
1797
resolveForwardRefForHotReloading(Component);
1798
}
1738
- child = updateForwardRef(
1799
+ return updateForwardRef(
1800
null,
1801
workInProgress,
1802
Component,
1803
resolvedProps,
1804
renderLanes,
1805
);
1745
- return child;
1746
- }
1747
- case MemoComponent: {
1748
- child = updateMemoComponent(
1806
+ } else if ($$typeof === REACT_MEMO_TYPE) {
1807
+ workInProgress.tag = MemoComponent;
1808
+ return updateMemoComponent(
1809
null,
1810
workInProgress,
1811
Component,
1812
resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
1813
renderLanes,
1814
);
1755
- return child;
1815
}
1816
}
1817
+
1818
let hint = '';
1819
if (__DEV__) {
1820
if (
1874
);
1875
}
1876
1817
-function mountIndeterminateComponent(
1818
- _current: null | Fiber,
1819
- workInProgress: Fiber,
1820
- Component: $FlowFixMe,
1821
- renderLanes: Lanes,
1822
-) {
1823
- resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
1824
-
1825
- const props = workInProgress.pendingProps;
1826
- let context;
1827
- if (!disableLegacyContext) {
1828
- const unmaskedContext = getUnmaskedContext(
1829
- workInProgress,
1830
- Component,
1831
- false,
1832
- );
1833
- context = getMaskedContext(workInProgress, unmaskedContext);
1834
- }
1835
-
1836
- prepareToReadContext(workInProgress, renderLanes);
1837
- let value;
1838
- let hasId;
1839
-
1840
- if (enableSchedulingProfiler) {
1841
- markComponentRenderStarted(workInProgress);
1842
- }
1843
- if (__DEV__) {
1844
- if (
1845
- Component.prototype &&
1846
- typeof Component.prototype.render === 'function'
1847
- ) {
1848
- const componentName = getComponentNameFromType(Component) || 'Unknown';
1849
-
1850
- if (!didWarnAboutBadClass[componentName]) {
1851
- console.error(
1852
- "The <%s /> component appears to have a render method, but doesn't extend React.Component. " +
1853
- 'This is likely to cause errors. Change %s to extend React.Component instead.',
1854
- componentName,
1855
- componentName,
1856
- );
1857
- didWarnAboutBadClass[componentName] = true;
1858
- }
1859
- }
1860
-
1861
- if (workInProgress.mode & StrictLegacyMode) {
1862
- ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
1863
- }
1864
-
1865
- setIsRendering(true);
1866
- ReactCurrentOwner.current = workInProgress;
1867
- value = renderWithHooks(
1868
- null,
1869
- workInProgress,
1870
- Component,
1871
- props,
1872
- context,
1873
- renderLanes,
1874
- );
1875
- hasId = checkDidRenderIdHook();
1876
- setIsRendering(false);
1877
- } else {
1878
- value = renderWithHooks(
1879
- null,
1880
- workInProgress,
1881
- Component,
1882
- props,
1883
- context,
1884
- renderLanes,
1885
- );
1886
- hasId = checkDidRenderIdHook();
1887
- }
1888
- if (enableSchedulingProfiler) {
1889
- markComponentRenderStopped();
1890
- }
1891
-
1892
- // React DevTools reads this flag.
1893
- workInProgress.flags |= PerformedWork;
1894
-
1895
- if (__DEV__) {
1896
- // Support for module components is deprecated and is removed behind a flag.
1897
- // Whether or not it would crash later, we want to show a good message in DEV first.
1898
- if (
1899
- typeof value === 'object' &&
1900
- value !== null &&
1901
- typeof value.render === 'function' &&
1902
- value.$$typeof === undefined
1903
- ) {
1904
- const componentName = getComponentNameFromType(Component) || 'Unknown';
1905
- if (!didWarnAboutModulePatternComponent[componentName]) {
1906
- console.error(
1907
- 'The <%s /> component appears to be a function component that returns a class instance. ' +
1908
- 'Change %s to a class that extends React.Component instead. ' +
1909
- "If you can't use a class try assigning the prototype on the function as a workaround. " +
1910
- "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " +
1911
- 'cannot be called with `new` by React.',
1912
- componentName,
1913
- componentName,
1914
- componentName,
1915
- );
1916
- didWarnAboutModulePatternComponent[componentName] = true;
1917
- }
1918
- }
1919
- }
1920
-
1921
- // Proceed under the assumption that this is a function component
1922
- workInProgress.tag = FunctionComponent;
1923
- if (__DEV__) {
1924
- if (disableLegacyContext && Component.contextTypes) {
1925
- console.error(
1926
- '%s uses the legacy contextTypes API which was removed in React 19. ' +
1927
- 'Use React.createContext() with React.useContext() instead.',
1928
- getComponentNameFromType(Component) || 'Unknown',
1929
- );
1930
- }
1931
- }
1932
-
1933
- if (getIsHydrating() && hasId) {
1934
- pushMaterializedTreeId(workInProgress);
1935
- }
1936
-
1937
- reconcileChildren(null, workInProgress, value, renderLanes);
1938
- if (__DEV__) {
1939
- validateFunctionComponentInDev(workInProgress, Component);
1940
- }
1941
- return workInProgress.child;
1942
-}
1943
-
1877
function validateFunctionComponentInDev(workInProgress: Fiber, Component: any) {
1878
if (__DEV__) {
1879
if (Component) {
3905
workInProgress.lanes = NoLanes;
3906
3907
switch (workInProgress.tag) {
3975
- case IndeterminateComponent: {
3976
- return mountIndeterminateComponent(
3977
- current,
3978
- workInProgress,
3979
- workInProgress.type,
3980
- renderLanes,
3981
- );
3982
- }
3908
case LazyComponent: {
3909
const elementType = workInProgress.elementType;
3910
return mountLazyComponent(
4027
renderLanes,
4028
);
4029
}
4030
+ case IncompleteFunctionComponent: {
4031
+ const Component = workInProgress.type;
4032
+ const unresolvedProps = workInProgress.pendingProps;
4033
+ const resolvedProps =
4034
+ workInProgress.elementType === Component
4035
+ ? unresolvedProps
4036
+ : resolveDefaultProps(Component, unresolvedProps);
4037
+ return mountIncompleteFunctionComponent(
4038
+ current,
4039
+ workInProgress,
4040
+ Component,
4041
+ resolvedProps,
4042
+ renderLanes,
4043
+ );
4044
+ }
4045
case SuspenseListComponent: {
4046
return updateSuspenseListComponent(current, workInProgress, renderLanes);
4047
}