Skip to content

Comments

fix(compiler): use Object.is() for cache dependency comparison to handle NaN#35885

Open
fresh3nough wants to merge 2 commits intofacebook:mainfrom
fresh3nough:fix/compiler-nan-cache-comparison
Open

fix(compiler): use Object.is() for cache dependency comparison to handle NaN#35885
fresh3nough wants to merge 2 commits intofacebook:mainfrom
fresh3nough:fix/compiler-nan-cache-comparison

Conversation

@fresh3nough
Copy link

Fixes #35854

Summary

The React Compiler generates cache dependency checks using strict inequality (!==), but this produces incorrect behavior for NaN values since NaN !== NaN is always true in JavaScript. This causes memoized values with NaN dependencies to be recomputed on every render, breaking the memoization guarantee.

React's runtime hook dependency comparison (in areHookInputsEqual) uses Object.is() semantics, which correctly handles NaN (Object.is(NaN, NaN) returns true). The compiler-generated code should be consistent with this behavior.

Changes

CodegenReactiveFunction.ts: Changed the dependency comparison codegen from $[n] !== dep to !Object.is($[n], dep), which correctly handles both NaN and -0/+0 edge cases, matching the runtime's Object.is semantics.

Before (generated code):

if ($[0] !== dep) { ... }

After (generated code):

if (!Object.is($[0], dep)) { ... }

How to reproduce

Create a component where a dependency evaluates to NaN:

function Component({ value }) {
  const derived = 0 / 0; // NaN
  const result = useMemo(() => [derived], [derived]);
  return result;
}

Before this fix, the memoized value would be recomputed on every render because NaN !== NaN is always true.

Test plan

  • Added cache-nan-dependency fixture that compiles a component with a NaN dependency
  • Updated all 859 existing fixture snapshots to reflect the new Object.is() comparison
  • Ran yarn prettier and yarn linc with no issues

@meta-cla meta-cla bot added the CLA Signed label Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Compiler Bug]: NaN in dependency list of useMemo always causes re-evaluation

1 participant