Fixes #35193 : Add runtime type check before calling useEffect cleanup functions #35194
+25
−20
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #35193
Summary
Adds runtime type checks to prevent crashes when non-function cleanup values are stored in effect hooks. This fixes the regression in React 19.x where returning
nullfromuseEffectcausesTypeError: destroy is not a functionduring cleanup.Currently, React only validates cleanup return values in DEV mode during effect mount, but doesn't check before calling cleanup during unmount in production.
Problem
When a non-function value (like
null) is stored ininst.destroy, React attempts to call it during unmount, causingTypeError: destroy is not a functioncrashes in production.Current behavior:
Related Issue: #35193
Solution
Added
typeof destroy === 'function'checks in two places:commitHookEffectListUnmount(line 267): Wraps cleanup execution in type check to prevent unnecessary profiling overheadsafelyCallDestroy(line 917): Defensive check as a safety netChanges
nullfrom useEffect causes crashesTesting
Code References
packages/react-reconciler/src/ReactFiberCommitEffects.jscommitHookEffectListUnmount(lines 248-302)safelyCallDestroy(lines 914-938)