skip to content

In a project built with the React Compiler, what does adding the directive "use no memo" at the top of a component or hook function body do, and when should you reach for it?

level: juniorimportance: nice to knowfreq 25%

answer

  1. a string literal, like 'use strict'
  2. inside the function, not the file header
  3. bisect tool, not a cure
  4. its opt-in twin exists for annotation mode
  5. every occurrence is a ticket

basics

~20 s

"use no memo" is a directive placed as the first statement of a function body that tells the React Compiler to skip that one component or hook, leaving it uncompiled. It is a temporary debugging escape hatch, not a permanent fix.

solid answer

~40 s

It opts a single function out of compilation. Written like `'use strict'` — as the first statement inside the component or hook body, not at the top of the file — it tells `babel-plugin-react-compiler` to leave that function exactly as written, so it re-runs every render with no caching. The intended use is diagnosis: if you suspect the compiler's memoization is behind a bug, add the directive to bisect, and if the bug disappears you have localised it to that component. It is not a fix, because what it usually reveals is impure render code that the compiler stopped paying to hide. Treat every occurrence as a ticket to resolve. Its counterpart is `"use memo"`, which opts a function *in* when the plugin runs in annotation mode.

go deeper

for a junior

Recall the exact form and placement: the string "use no memo" as the first statement inside the component function, and its effect is that the compiler leaves that one function alone.

for a middle

Explain the workflow it belongs to — add it to bisect a suspected memoization bug, confirm, then hunt the impurity — and contrast it with the opt-in "use memo" used in the compiler's annotation mode.

for a senior

Argue that the directive is a diagnosis, not a remedy: a component that only works uncompiled has an impure render that was already a bug, and shipping the opt-out preserves it. Say what you would do to find the real cause.

for a principal

Set the policy: opt-outs need an owner and an expiry, are surfaced in review, and are counted as technical debt against the adoption goal, since each one is both an unoptimised component and a known latent defect.

## What a directive is here A directive is a bare string literal as the first statement of a body, the same syntactic slot as `'use strict'` at the top of a function. The React Compiler reads two of them: - `"use no memo"` — do not compile this function. - `"use memo"` — do compile this function. They go **inside** the function, which is what distinguishes them from `'use client'` and `'use server'`, the module-level directives that go at the top of a file above the imports. Confusing the two placements is a common slip in interviews. ```jsx function FlakyWidget(props) { "use no memo"; // compiled output for this function is just the source, unmemoized return <div>{render(props)}</div>; } ``` ## What each one is for `"use no memo"` is an escape hatch for debugging. In its default inference mode the compiler compiles everything it can prove safe, and occasionally a component misbehaves once its output is cached. Adding the directive to that component and seeing the bug vanish is a fast, surgical bisect: you have proved the problem is in the interaction between that function and memoization, without reverting the plugin for the whole app. `"use memo"` is the opposite, and it exists because of the plugin's `compilationMode` option. In the default `'infer'` mode you never need it. In `'annotation'` mode the compiler only touches functions carrying `"use memo"`, which is the standard way to pilot the compiler on a handful of components before rolling it out to a whole codebase. ## Why the opt-out is temporary by design When memoization changes a component's behaviour, the memoization is rarely the defect. Reusing a cached result is safe for a pure function, so a component that breaks under caching is telling you it is not pure: it mutates a prop, a context value or a module-level object during render, reads or writes a ref during render, or depends on being re-run for some side effect. The uncompiled build hid the bug by recomputing everything every time. So the correct sequence is: add the directive, confirm the bug goes away, find the impurity, fix it, delete the directive. A `"use no memo"` left in the codebase is a component permanently excluded from optimisation *and* a component with a known-latent bug — worth flagging in review, and worth grepping for periodically. ## What it does not do It does not disable React features. Automatic batching, concurrent rendering, StrictMode's development double-render and everything else in React behave identically; the directive only removes the compiler's caching from one function. It also does not stop the component from re-rendering — quite the opposite, it re-renders and recomputes exactly as pre-compiler React always did. And it does not affect the component's children: a child that the compiler compiled stays compiled, it simply no longer receives cached props from this parent. ## What an interviewer is checking Three things: that you know the directive is function-scoped and goes in the body (not a file header like `'use client'`); that you frame it as a diagnostic bisect tool rather than a fix; and that you can name the counterpart `"use memo"` and the annotation mode it belongs to. Saying "it turns off memoization for that component" is correct but thin; adding "and the reason I needed it is usually an impurity worth fixing" is the answer that lands.

  • How does "use no memo" differ in placement from 'use client'?
    `'use client'` is a module-level directive: it goes at the very top of a file, above the imports, and marks the whole module as a client boundary. `"use no memo"` is function-scoped — the first statement inside a component or hook body — and affects only that one function. Putting either in the other's position simply does nothing.
  • When would you ever write "use memo" instead?
    When the compiler is running in annotation mode (`compilationMode: 'annotation'`), where nothing is compiled unless it opts in. That is the usual pilot setup: mark a few low-risk components with `"use memo"`, verify behaviour and profile the result, then widen the scope or switch to inference mode once you trust it.
  • You find a "use no memo" that has been in the codebase for six months. What do you do with it?
    Treat it as an open bug, not settled configuration. Remove it locally and reproduce the original failure, then look for the impurity in that component — mutation of props, context or module state during render, or a ref touched during render. Fix that and delete the directive; if it genuinely cannot be fixed now, at least attach an issue so it is not silently permanent.

saying these in an interview costs you the question

  • Puts the directive at the top of the file like 'use client'
  • Says it stops the component from re-rendering
  • Treats it as the permanent fix for a compiler-related bug
  • Thinks it disables batching or concurrent rendering for that component
  • Confuses it with the opt-in "use memo" directive

context