"Nothing changed... why is it re-rendering again?"

If this sounds familiar — here’s a quick breakdown of why it happens and how to control it.


1. New Objects, Arrays, or Functions in Props

React does a shallow comparison of props. That means if you pass a new object or array (even if it contains the same data), React sees it as "changed" — and triggers a re-render.

Example:

// This will trigger a re-render because `data` is a new object on each render
<Component data={{ name: "Dima" }} />

Slution:

Use useMemo to memoize objects or arrays:

const memoData = useMemo(() => ({ name: "Dima" }), []);
<Component data={memoData} />

2. Parent Re-renders = Child Re-renders

If a parent component updates, all of its children re-render by default — even if their props haven’t chaned.

Example:

const Parent = () => {
  const [count, setCount] = useState(0);
  return (
    <><button onClick={() => setCount(count + 1)}>Increase</button>
      <Child />
    </>
  );
};

const Child = () => {
  console.log("Child re-rendered");
  return <div>Child</div>;
};

In this example, every time Parent re-renders, Child also re-renders even if its props haven’t changed.

Solution:

Wrap child components in React.memo to prevent unnecessary updates:

const Child = React.memo(() => {
  console.log("Child re-rendered");
  return <div>Child</div>;
});

3. Memoization Isn’t a Silver Bullet

React.memo only performs shallow comparison. If a prop is a new object or function every render, it still triggers a re-render — even with memoization.