[@mantine/core] Fix NaN handling in shallowEqual and useShallowEffect #7851
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.
Description
This pull request addresses an issue where
useShallowEffect
would incorrectly re-trigger when a dependency wasNaN
in both the previous and current renders. React's nativeuseEffect
hook treatsNaN
as equal toNaN
for dependency comparison (followingObject.is
semantics), meaning the effect does not re-run in such cases. This change bringsuseShallowEffect
's behavior in line withuseEffect
forNaN
values.The root cause was the
shallowEqual
utility function, which previously treatedNaN
as not equal to itself (NaN !== NaN
istrue
under strict equality).Changes Made
The primary modifications were made to the
shallowEqual
function to ensureNaN
values are considered equal:Top-Level NaN Argument Handling:
shallowEqual
to returntrue
if both top-level argumentsa
andb
areNaN
.shallowEqual(NaN, NaN)
now correctly evaluates totrue
.Property Value NaN Handling:
a[key]
andb[key]
are not strictly equal (a[key] !== b[key]
), an additional check is performed. If both areNaN
, they are now considered equal for the purposes ofshallowEqual
.{ value: NaN }
and{ value: NaN }
are considered shallowly equal if their other properties also match.These changes specifically target
NaN
comparison usingNumber.isNaN()
and preserve the existing===
strict equality behavior for all other value comparisons (e.g.,0
and-0
remain equal, as per original behavior). This approach avoids unintended side effects that a broader switch toObject.is()
for all comparisons might introduce.Impact
useShallowEffect
anduseShallowCompare
: These hooks now correctly handleNaN
values in dependency arrays. An effect managed byuseShallowEffect
will no longer re-run unnecessarily if a dependency changes fromNaN
toNaN
.useShallowEffect
more closely with React's nativeuseEffect
concerningNaN
dependencies.This fix ensures more predictable and correct behavior for shallow comparison involving
NaN
values.