DEV Community

Cover image for The Importance Of Immutability In React
Vasil Vasilev
Vasil Vasilev

Posted on

The Importance Of Immutability In React

Immutability is a crucial concept in React. It refers to the practice of not changing the original data structures once they are created. Instead, when modifications are required, new data structures are created to represent the updated state.

Why is immutability manually applied?

In JavaScript, objects and arrays are reference types. When you mutate an object, its reference remains the same, even if the content changes. This can lead to unexpected behavior when comparing objects for equality or when checking for changes. Immutable data ensures that changes result in new references, facilitating accurate comparison checks.

Why is immutability encouraged in React specifically?

  1. Predictable Data Flow: In React, components re-render when their state or props change. If the data within a component's state is immutable, it becomes easier to predict when a re-render will occur. This predictability is essential for maintaining a stable and efficient application performance.

  2. It improves performance: React uses a virtual DOM to render components. The virtual DOM is a lightweight representation of the actual DOM. When an object is immutable, React can simply compare the old and new objects to see if anything has changed. If nothing has changed, React can skip the rendering step, which can improve performance.

  3. Debugging: It can help to prevent bugs. When objects are immutable, it is more difficult to accidentally modify the state of an object in a way that can cause a bug.

How to achieve immutability in React?

One way is to use the const keyword to declare variables. Variables declared with the const keyword cannot be changed.

// bad: Because a new object is created every time React renders.

function App() {
  const [visible, stop] = useElementVisibility(ref, {
    root: null,
    rootMargin: "0px",
    threshold: 1,
  });
}

const options = {
  root: null,
  rootMargin: "0px",
  threshold: 1,
};

// good: Because the reference to the object remains unchanged.

function App() {
  const [visible, stop] = useState(ref, options);
}
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can choose to use the useMemo function to wrap it.

// good: Because the reference to the object remains unchanged.

function App() {
  const options = useMemo(() => {
    return {
      root: null,
      rootMargin: "0px",
      threshold: 1,
    };
  }, []);

  const [visible, stop] = useState(ref, options);
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)