Object Immutability: How it helps React
Tags: javascript, webdev, react, frontend
Published: 2022-02-13 08:33:46

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>;
}
```
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>;
}
```
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!