DEV Community

Nishad Vijayakumar
Nishad Vijayakumar

Posted on

Object Immutability: How it helps React

React is all about DOM and state tracking isn't it?!?!

Whoaaa!! Hold on & let's not jump the gun here. How about we try to understand each and every bit of the first sentence.

As we know, DOM is the essence of any HTML content you see on a webpage. And React framework is used as a tool to manipulate DOM programmatically in JSX. That's it, that should be a good enough start to understanding how object immutability comes into play in the world of React.

Objects(dictionary in python, HashMap in Java) and Arrays in Javascript are objects similar to what we know or should know rather that every instance of it refers to a new address in memory.

For example:
new Array(); // creates []
new Object(); // creates {}

refers to instances of an array and an object which will have its own HEX address reference in the memory.

Now, if we do this:
new Array() === new Array() : returns False
new Object() === new Object(): returns False

How about we do:
const first_array = [];
const second_array = first_array;
console.log(first_array === second_array) // true and expected

first_array.push(10);
console.log(first_array === second_array); // true and unexpected

We say that .push is a method that mutates the array which means it's a method that changes the array.

Why are we doing all of this? In short, React needs a way to know in an efficient manner if you've changed the state (when it's an array or object).

What is Immutability?
An immutable object is an object that cannot be changed. Every update creates a new value, leaving the old one untouched.

This is a fundamental concept when working with arrays and objects in React.

Why not "deep equal"?
Deep equal is when you compare 2 objects based on their values.
With a deep equal, [] would be equal to []. Same for {key: "something"} and {key: "something"}.
However, JavaScript does NOT have a built-in method for deep equal, which means you will have to resort to an external library or a hack, which is dirty and not an efficient solution.

Let's dig into an example here:

import React, {useState} from "react";

function App(){
  const [data, setData] = useState([]);

  function handleAddClick(){
      data.push(10)
      setData(data);
  }

  return <button onClick={handleAddClick}>Add 10</button>;
}
Enter fullscreen mode Exit fullscreen mode

In the function handleAddClick above, data array is getting mutated when 10 gets pushed. And, please note that the state(or rather the address) of that array object still remains intact. However, React needs to know if there was any change in "state" before updating DOM efficiently based on this aspect. In our case, the "state" hasn't changed at all.

How do we fix this?

import React, {useState} from "react";

function App(){
  const [data, setData] = useState([]);

  function handleAddClick(){
      setData(...data, 10);
  }

  return <button onClick={handleAddClick}>Add 10</button>;
}
Enter fullscreen mode Exit fullscreen mode

In the function handleAddClick above, spread operator(...) creates a copy of the data array and appends 10 to it. This makes an immutable change rather than a mutable one since we made a copy of that array and THEN modified it. This is sufficient for React to let the DOM know that something has changed. And voila, this is a start to Object Immutability.

Hope the concept was clear and it all made sense. Thanks!

Top comments (0)