· Tech · 4 min read
React: Why Prop Change Does NOT Cause Re-render
A relatively deep dive into React's re-render mechanics, why prop changes alone don't trigger re-renders, and how state libraries like Jotai and Recoil manage surgical updates. Includes step-by-step code and practical patterns.

No, Prop Change DOES NOT Cause Re-render — It’s Just a Myth
When Component Re-Renders and How Library Can Bring State From Outside
Understanding how and when a component re-renders is essential for every React developer. Even those with significant experience have likely been caught off guard by not knowing the details.
So here is a quiz.
A React Component Re-renders When:
- Its state updated
- Its props change
- Its parent rerenders
- Its context updated
Of those choices, which one of them are NOT true?
The answer is…
No, a component DOES NOT rerender when props change.
It does not. React has no way of knowing when a prop changed. By design, React only knows when to rerender when the state updates, or a parent rerenders, or the context changes.
Consider the following example:
let count = 0;
const Parent = () => {
useEffect(() => {
const intervalId = setInterval(() => {
count++;
console.log("count: ", count);
}, 300);
return () => {
clearInterval(intervalId);
};
}, []);
return <Child count={count} />;
};
const Child = (props) => {
return <p>{props.count}</p>;
};The setInterval callback will run, but the Child component won’t be rerendered as it should not be, because React has no way to know the prop has updated.
Here is how rerendering happens.
When the parent rerenders
This is intuitive and straightforward.
When the context updates
When a context is updated, the component tree below the context provider rerenders. This is also easy to reason about.
When state updates
When a component updates its state using useState, it sets a flag on itself and also notifies its ancestors all the way up to the root that a child has changed. This signals to React that a re-render is needed. React then traverses the component tree from the root, looking for these flags. When it finds a flagged component, it re-renders it, checks for differences, and commits the changes to the DOM.
How do state libraries manage surgical updates?
State libraries like Recoil or Jotai can subscribe to a simple state from multiple components, regardless of the component tree. Jotai can tell React to rerender only subscribed components when the value is updated.
A very simple example of how you can do it is like this. They just use useState under the hood, but only the setter function. How? Here is a PoC code:
let value;
const listners = new Set();
const useMyValue = () => {
// This local state is not used as the source of truth.
// It only exists to give React a reason to re-render this component.
const [, setTrigger] = useState(value);
useEffect(() => {
// Register this component as a subscriber.
// When the shared value changes, this callback will run.
const listner = (v) => setTrigger(v);
listners.add(listner);
return () => {
// Remove the subscription when the component unmounts.
listners.delete(listner);
};
}, []);
// Always read the latest value from the external store.
return value;
};
const useSetMyValue = () => {
// This hook only returns a writer.
// It does not subscribe, so using it alone does not make the component re-render.
return (myValue) => {
// Update the external value first.
value = myValue;
// Then notify every subscribed component.
// Each subscriber will call its own setTrigger, which asks React to re-render it.
listners.forEach((fn) => fn(myValue));
};
};// Sample usage:
const MyComponent = () => {
return (
<div>
<DisplayValue />
<UpdateValue />
</div>
);
};
const UpdateValue = () => {
// This component only gets the setter.
// It does not subscribe to the value, so clicking the button does not re-render this component.
const setValue = useSetMyValue();
return <button onClick={() => setValue(Math.random())}>Click</button>;
};
const DisplayValue = () => {
// This component subscribes to the shared value.
// When the button updates the value, this component receives the notification and re-renders.
const myValue = useMyValue();
return <div> my value is: {myValue} </div>;
};Key Takeaways
- React only rerenders when state, context, or parent changes—not just when props change.
- State libraries can surgically rerender only subscribed components by using custom subscription logic.
- Separating read and write hooks allows for precise control over which components rerender.