Skip to main content
Zhimalab
中文

useMemo in React: Giving the Wild Butterflies a Chair

Wed Dec 10 2025 08:00:00 GMT+0800 (中国标准时间) · 11 min

Writing code is like living life — the worst thing is to fidget.

When you have no sense of what’s happening, your hands and feet go wild. React is the same: the moment your state changes, it panics and recomputes the whole component from top to bottom. Like a lovestruck newbie: the girl replies “mm”, and his brain has already planned which kindergarten their kid will attend.

That kind of “diligence” is sometimes a disaster.

The restless butterflies

We were just fixing that little Word Dictation tool. There were a few butterflies in the background — pretty, even poetic. But the moment you hit a key and type a letter, the butterflies went berserk, flickering across the whole screen.

Why? Because the butterflies’ positions are randomly generated:

// the naive way
const flowers = [...Array(12)].map(() => ({
  left: `${Math.random() * 100}%`, // random every time
  top: `${Math.random() * 100}%`
}));

You type a key, userInput changes, the component re-renders. React reaches this line, sees Math.random(), and thinks: “Ah, the master wants randomness, so I’ll give you another one.”

So every keystroke is a Big Bang — the butterflies teleport from one hemisphere to the other in milliseconds. That’s not “lively”; that’s ADHD. That’s a physiological tremor caused by inner uncertainty.

useMemo: composure in code

How do you fix it? You need composure.

In React, that composure is called useMemo.

What is Memo? It’s Memory. It’s the one little bit of certainty you grasp in the unsteady river of time.

We want to tell React: “These butterflies’ positions only need to be computed once. Unless the sky falls (the dependencies change), don’t touch them.”

So we added this chair:

// the composed way
const decorations = React.useMemo(() => {
  // the code here only runs once, on the component's first meeting
  // like first love — only once; everything after is just everyday life
  return {
    flowers: [...Array(12)].map(() => ({
      left: `${Math.random() * 100}%`,
      top: `${Math.random() * 100}%`
    })),
    butterflies: [...Array(6)].map(() => ({
      // ...
    }))
  };
}, []); // an empty array means a heart still as water — I don't change no matter who changes

With useMemo in place, you type again — userInput can change however it wants, React walks up to this line, pulls the note it computed last time from its pocket, and says: “Same butterflies, same positions, take them.”

The butterflies stop moving, and the mind goes quiet. The screen stops flickering, and the world is beautiful again.

When should you use it?

Don’t overuse it.

Some programmers, once they learn useMemo, want to memoize even 1 + 1. That’s another illness, called “over-optimization”, called “stinginess”.

There are only two situations worth spending your composure on:

  1. The computation is too expensive: computing it once costs half your life — e.g. processing tens of thousands of records, or complex math. That’s when you want to use your brain sparingly.
  2. The reference is too fragile: like this time. The computation isn’t expensive (just generating a few random numbers), but we need reference stability. If a new object is created every time, child components think the data changed and mess around accordingly — or, like this time, it causes visual “jitter”.

Ending

When you write code to the end, what wins isn’t typing speed — it’s temperament.

Knowing when to move and when not to move — that’s advanced.

useMemo is React’s gift to you: the right to “not fidget”. Used well, your code gains a golden thread; used poorly, it’s just more tangled logic stuffed into already-complicated code.

No matter how flamboyantly butterflies fly, their landing spot must be steady.

That’s all.