dillon1000/react
Commit
Browse files [Fast Refresh] Remount correctly when an edit changes the component kind (#36950)
Fixes #30659. I'm not confident in this yet but here's what Fable said based on https://github.com/react/react/pull/32214#issuecomment-2734436781: Editing a component from a plain function to a memo or forwardRef wrapper (or between wrapper kinds) crashed with "Component is not a function", because canPreserveStateBetween only compared hook signatures. The edit was classified as state-preserving, so createWorkInProgress swapped the wrapper object in as the type of a FunctionComponent fiber and renderWithHooks tried to call it. Two fixes, both DEV-only: - canPreserveStateBetween returns false when typeof or $$typeof differ. A fiber's tag is derived from the kind of its type, so state can never be preserved across a kind change; these edits must go to staleFamilies (remount). Nested wrappers need no special handling because register() creates a family per nesting level ($type/$render ids), and each level's kind is compared against its own family. - The reconciler now finds and remounts wrapper fibers whose outer kind changed. scheduleFibersWithFamiliesRecursively previously resolved families only through the inner implementation (type/type.render), but a kind-changing edit is recorded only on the outer type's family, so edits like memo -> function never reached the scanner and were silently dropped. The scanner now also checks the elementType's family, and the _debugNeedsRemount branch in beginWork rebuilds the fiber from family.current (the latest registered type for the fiber's identity) rather than the fiber's possibly-stale inner type. This also fixes stale simple memo remounts recreating as plain functions, dropping the memo wrapper. Unlike the reverted #30660 (see #32214), this does not fabricate families or guess type shapes: families are still created in exactly one place, and the same ID always resolves to the same family. Restores the tests from #30660 and adds coverage for changing the inner type of a memo between function and forwardRef. Co-authored-by: BIKI DAS <[email protected]> Co-authored-by: dan <[email protected]>
Changed paths4 files
First-parent comparisonpackages/react-reconciler/src/ReactFiberBeginWork.js ModifiedM packages/react-reconciler/src/ReactFiberHotReloading.js ModifiedM packages/react-refresh/src/ReactFreshRuntime.js ModifiedM packages/react-refresh/src/__tests__/ReactFresh-test.js ModifiedPatch
Files changed
Rendering syntax-highlighted changes…