React

Why does React state need a new object/array?

Advertisements

If you have been using React for a while, you are familiar with how state update works. There are a lot of internal optimizations that React makes for faster rendering. One of the implementation details of the React internals is that it checks whether the given state object has actually changed or not. But the behavior of assigning a new object/array trips up newcomers. Let us understand why React needs a new copy of an object/array when assigning state.

Object.is() in JavaScript

Object.is() is a comparison operator in JavaScript. It is attached to Object.prototype and can be used to compare JavaScript values, both object as well as primitive values.

For an object:

const author1 = {name: "Saransh Kataria"};
const author2 = {name: "Saransh Kataria"};

Object.is(author1, author2); // false
JavaScript

Since objects are stored by reference, the comparison returns false.

How is this relevant with respect to React?

React uses Object.is() for comparison of the previous and next states to determine whether or not to update the DOM. The relevant part for that case is:

const author1 = {name: "Saransh Kataria"};
author1.name = "Wisdom Geek";

Object.is(author1, author1); // true
JavaScript

Since we are mutating the same object and it’s properties, the comparison will always return true.

Therefore, when we do:

const [author, setAuthor] = useState({name:"Saransh Kataria")};

const updateName = () => {
  author.name = "Wisdom Geek";
  setAuthor(author)
}
JavaScript

In the update name function, we are updating the author object. And send the updated object to setAuthor. This will not update the UI even though we have updated the author object.

Why is the User Interface not updated?

As we saw previously, changing a property on an object does not change the reference of that object. React uses Object.is() under the hood to determine whether the state was updated or not when we invoke the setter function.

Since the object reference did not change, Object.is() returns false even though we updated some properties. Therefore, React does not feel the need to update the UI because nothing has changed according to it.

To get it to work correctly, we must pass in a new reference to the useState function. And for doing that, we need to create a new object. Once we do that, Object.is() will return true because the references will not be the same, and we will trigger a re-render.

const updateName = () => {
  setAuthor(prevState => {...prevState, name: "Wisdom Geek"});
}
JavaScript

This uses the spread syntax and the callback function to update the state. We return a new object which does not have any properties that are directly referenced from the initial object. And we also update the property that we wanted to update.

The same logic applies to arrays as well since they are reference types as well.

Conclusion

I hope that that explanation demystifies React internals and gives a better idea about the implementation detail of state management in React. If you have any questions, feel free to drop a comment below!

Saransh Kataria

Born in Delhi, India, Saransh Kataria is the brain behind Wisdom Geek. Currently, Saransh is a software developer at a reputed firm in Austin, and he likes playing with new technologies to explore different possibilities. He holds an engineering degree in Computer Science. He also shares his passion for sharing knowledge as the community lead at Facebook Developer Circle Delhi, NCR which is a developer community in Delhi, India.

Share
Published by
Saransh Kataria

Recent Posts

How To Get The Hash of A File In Node.js

While working on a project, I wanted to do an integrity check of a file…

2 days ago

Native popover API in HTML

Popovers have been a problem that was typically solved by using a third-party solution. But…

1 week ago

Node.js 20.6 adds built-in support for .env files

Node.js 20.6 added built-in support for the .env file. This is an excellent addition to the platform…

2 weeks ago

Object destructuring in TypeScript

Object destructuring is a powerful ES 6 feature that can help developers write cleaner code.…

1 month ago

Improve git clone performance in a CI pipeline

Have you felt particularly annoyed by the time it takes to clone a large repository,…

1 month ago

Fix: Hydration failed because the initial UI does not match what was rendered on the server

Within a React or Next.js app, if you encounter the error "Hydration failed because the…

2 months ago
Advertisements