One of the greatest sources of confusion for new and experienced React developers alike is what actually causes a component to re-render. Fully covering render behavior in React would take several posts, so I want to use this post to highlight one specific misconception that many engineers have regarding re-renders. Specifically, the incorrect assumption that a component will re-render when its props change.
The best way to clear up this misconception is with an example. Let’s create a basic app that has two components, a parent and a child, that each display a count value. The count state will be stored in the parent and passed as a prop to the child, but it will be rendered in both components. Here’s the code.
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<p>Parent Component</p>
<p>Count: {count}</p>
<Child count={count} />
<button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
</div>
);
}
function Child({ count }: { count: number }) {
return (
<div>
<p>Child Component</p>
<p>Count: {count}</p>
</div>
);
}
When the “Increment” button is clicked, you’ll observe that the count value updates in both the parent component and the child component. This shouldn’t be too surprising.

Why is the child component re-rendering, though? It seems like a basic question, but it’s one that many don’t fully understand. You might think that it’s re-rendering because the count
prop is changing, and while this seems like an intuitively correct answer, it’s incorrect. To illustrate this, let’s update the example a bit.
function Parent() {
const count = useRef(0);
const incrementCount = () => count.current++;
return (
<div className="parent">
<p>Parent Component</p>
<p>Count: {count.current}</p>
<Child count={count.current} />
<button className="button" onClick={incrementCount}>
Increment
</button>
</div>
);
}
The child component hasn’t changed, but we’ve updated the parent component to store the count
value in a ref
instead of in React state. Let’s see what happens after making this change.

That’s strange; nothing’s happening. Let’s add a console log statement to the increment
count handler to make sure it’s being updated as expected.

The count is definitely being updated, so what’s going on? Why isn’t the parent component or the child component re-rendering?
The reason is that mutating a ref
doesn’t cause a re-render. This isn’t the main point of the post, but it’s important to understand. According to the React docs, a ref
should be used when:
you want a component to “remember” some information, but you don’t want that information to trigger new renders
Updating the ref in the parent component doesn’t trigger re-render. But the value is definitely still changing, so if it were the case that components re-render when their props change, we would expect the child component to re-render.
Based on what we’ve observed here, we can confidently say that a prop change alone does not cause a component to re-render. One thing that does cause a component to re-render is when its parent component renders, which is exactly what we were seeing in the example that used React state to store the count value. Updating state in a component causes it to re-render. The parent component re-rendered when the state was updated, and the child component re-rendered as a consequence of that render.
It’s worth emphasizing that when a parent component re-renders, all of its child components will re-render even if they accept no props, or if the props they do accept haven’t changed. Let’s confirm this by modifying our original example (the one using React state).
function AnotherChild() {
console.log("log: another child render");
return <div className="another-child">Another child component</div>;
}
We added a new component, AnotherChild
, that takes no props and is a child of Parent
.

As you can see in the console, AnotherChild
re-renders when Parent
re-renders, even though it accepts no props. You might be thinking that React should be smart enough to know that AnotherChild
doesn’t need to re-render, but unfortunately it’s not.
One workaround for this is React’s memo
function, which wraps a component and only re-renders the component when the props have changed. Let’s update our example to see this in action.
const AnotherChild = React.memo(() => {
console.log("log: another child render");
return <div className="another-child">Another child component</div>;
});
All we need to do is wrap the component definition in React.memo
. Now, AnotherChild
only renders once; it doesn’t re-render when the parent component renders due to a state change.

There’s much more to go over to fully understand React.memo
, but I’ll save that for a future post.
Rendering in React is a complex topic that can cause a lot of confusion. Here are some resources I’ve found helpful in gaining a more comprehensive understanding of the topic.
Intro to re-renders - Nadia Makarevich
Why React Re-Renders - Josh Comeau