Are Primitive Values Recreated on Every Re-Render in React Functional Components?

In the context of a React functional component, when a re-render occurs, the old values and objects inside its function body are garbage-collected. For objects and functions, a new reference is created in memory, while for primitives new values are assigned to variables in memory.

Despite the fact that primitives receive new values, they're still the same values from the previous re-render (unless explicitly changed). Therefore, when comparing these values, such as in the dependency array of hooks, the callback of the hook is not triggered. This is due to the fact that, unlike objects, primitives are compared by value rather than by reference.

For this reason, it is generally safe to declare a primitive value directly inside a function body as, for example, it will not cause a hook to run on every re-render when a reactive value changes:

// MyComponent.jsx
import React, { useState, useEffect } from 'react';

export function MyComponent() {
  const [foo, setFoo] = useState('');

  // every time `foo` changes, this will be the same value
  const primitive = 123;

  useEffect(() => {
    console.log('effect was run');
  }, [primitive]);

  return (
    <button onClick={() => setFoo(Math.random())}>Foo</button>
  );
}

In this example, the reason the primitive value does not cause the effect to run on every re-render when the reactive value "foo" changes is because primitive values are compared by value rather than by reference. Unlike objects, where a new reference is created on each re-render, the value of primitive remains the same across re-renders.


This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.