DEV Community

Cover image for The big secret of React
Axel Navarro for Cloud(x);

Posted on

The big secret of React

Have you thought about how React compares the deps array used by the hooks in every render? Let's check the magic that decides when to run the useEffect hook.

Introduction

As a curious developer, I was wondering how React checks the dependencies array -called deps- that is passed to the useEffect, useCallback and useMemo hooks. I didn't find the answer anywhere.

useEffect(() => {
  console.log('someValue has changed:', someValue);
}, [someValue]);
Enter fullscreen mode Exit fullscreen mode

So, my only option was to check the React's code itself to find the magic, and I found more than I expected.

The comparison

React doesn't use == or === operators, it uses the Object.is() method. This method provides the SameValue algorithm since ES2015.

We all know the difference between Abstract Equality Comparison (==) and Strict Equality Comparison (===), but what comes with this new comparison?

πŸ’‘ You can quickly check the differences between these equality algorithms in MDN.

We can affirm that the differences between === and Object.is are:

  1. +0, -0 and 0 result in the same value for ===, but different for Object.is. Β«And that's a point to is for being mathematically correct.Β» βœ…
  2. NaN === NaN is false for === πŸ˜’, but true for the SameValue algorithm. Β«Another point to Object.is.Β»

I think now it's clearer why React choses a little-known comparison method.

Show me the code

If you're a developer, I guess you want to see where is the code for Object.is 😁. The answer is in a function called areHookInputsEqual in the ReactFiberHooks.new.js file: https://github.com/facebook/react/blob/v18.1.0/packages/react-reconciler/src/ReactFiberHooks.new.js#L323.

πŸ’‘ I used the latest tag because the code changes continuously.

It's cool to see how this check is completely ignored if you're in a hot reload process, and how the checks for the programmer are removed in the production build of React.

Conclusion

IMO the most important issue here is that React doesn't make a deep comparison between objects, it only checks if they're the same object.

πŸ’‘ If you don't know what this means check this Redux page about the benefits of immutability.

🧠 Remember that an object variable is just a memory reference (pointer) to where the object is, that's what === and Object.is use when you compare two objects.

I hope you enjoyed this dive into the React's source code. 🀿

Discussion (2)

Collapse
geforcesong profile image
George Guo

great article

Collapse
navarroaxel profile image
Axel Navarro Author

Thanks!