Memoization in React: Or How I Thought I Optimized My App (But Mostly Just Felt Productive)
Source: Dev.to
If you’ve been writing React for a while, there’s a phase you inevitably enter:
The “performance phase.”
You stop worrying about getting things to work and start worrying about getting things to work fast. You start side‑eyeing re‑renders like they owe you money, open React DevTools more than Slack, and eventually Google:
“How to prevent re‑renders in React?”
React, in its infinite wisdom, answers with three magical words:
useMemouseCallbackmemo
You read a few blog posts, watch a YouTube video at 1.25× speed, sprinkle some memoization into your code like seasoning, and—voilà—✨ Optimized. ✨
Or… so you think.
That was me—for a long time. I felt like I was writing performant React, but I decided to stop trusting vibes and actually observe how React behaves in a few scenarios. What I found was humbling: I had been “optimizing” my app in ways that felt productive but didn’t actually do what I thought they did.
Today I’ll walk you through some not‑so‑obvious misconceptions about memoization in React, using this repo as our playground:
👉 Repo:
If you disagree with anything—or if something clicks for you—please yell (politely) in the comments.
Before We Get Fancy, Let’s Agree on Some Facts
A React component re‑renders when:
- Its internal state changes
- Its parent re‑renders
Some people add a third rule:
- Its props change
Personally, I think #2 already covers that. If you disagree, feel free to fight me in the comments. I’m open. 😄
Keep these two rules in mind—we’ll keep coming back to them like a lecturer pointing at the same slide over and over saying “this will be on the exam.”
Misconception #1
“Passing memoized values into a component prevents re‑renders”
Short answer: Nope.
Long answer: Let me show you why I fell for this too.
Switch to the without-memoized-component branch in the repo. You’ll see two components:
memoized-component.tsx

(pretend I’m dramatically pointing at it)
App.tsx

(nod thoughtfully)
Notice something important in App.tsx: we’re using useCallback before passing a function down as a prop. At this point, past‑me was already celebrating.
“The function is memoized. React won’t re‑render the child. I am a performance genius.”
Now click the count button:

The child component re‑renders every single time.
“But the function isn’t changing!”
Correct. Gold star ⭐ The function reference is stable.
But remember the rules. Go back to rule #2: a component re‑renders when its parent re‑renders. The parent’s state changed, so the parent re‑rendered, and therefore the child re‑rendered.
useCallback didn’t fail you—your expectations did (mine too). In this scenario, useCallback is basically emotional support: it makes you feel better but doesn’t actually stop anything.
“So… how do we fix it?”
Easy. Wrap the child component with memo, then refresh the app (yes, actually refresh it) and click the button again:

No re‑render. Now we’ve achieved what we thought we had achieved earlier.
Lesson: Memoizing props without memoizing the component does absolutely nothing for re‑renders.
Misconception #2
“If I memoize a component, I’m safe”
memo only prevents re‑renders when props don’t change. React checks this using shallow comparison. So if you do any of the following, React sees a new reference and re‑renders:
- Pass an inline function
- Pass a freshly created object
- Pass a derived value that isn’t memoized
At that point, your memo wrapper is just decorative.
You can test this yourself:
- Remove
useCallbackfromApp.tsx - Click the button
- Watch the render count climb like it’s training for cardio
The painful truth
Memoizing a component without memoizing the values you pass into it is like locking your front door and leaving the windows wide open. It looks secure—isn’t.
Bottom line
Understanding when and what to memoize is crucial. Use useCallback/useMemo to keep prop references stable, and wrap components with memo only when you know the props truly stay the same between renders.
Memoization has:
- a mental cost
- a maintenance cost
- and sometimes even a performance cost
It shines only when:
- re‑renders are expensive
- props are stable
- you’ve measured a real problem (not just a feeling)
I’ll dive deeper into when memoization actually makes sense in another article.
Final Thoughts (From Someone Who Learned the Hard Way)
For a long time, I thought I was writing performant React because I was using the right tools.
What I wasn’t doing was:
- observing behavior
- questioning assumptions
- understanding why React was re‑rendering
Memoization isn’t magic.
It’s just a tool.
And like all tools, it works best when you actually know what it does.
If I got anything wrong, misunderstood something, or if this post helped you see memoization differently, drop a comment. I’d genuinely love to hear your thoughts.
See you in the next one 👋