use nemo
"use nemo" forbids React Hook usage inside a function. The React Compiler will surface an error if the function calls anything that looks like a Hook (for example useState or a custom useSomething helper). The directive name nods to Nemo—the famously hook-averse clownfish from Finding Nemo—reminding us that real fish hate hooks and so should this component.
Reference
"use nemo"
Place "use nemo" at the very top of a function body to declare it as a hook-free zone.
function FishFacts() {
"use nemo";
// ✅ Regular code is fine
const [facts] = getFacts(); // Not a Hook, just a regular helper
return <FactsList facts={facts} />;
}
If you care about fish, give them a hook-free habitat.
When the compiler sees "use nemo", it rejects any React Hook calls inside the function (including custom Hooks). The directive is useful when you want to guarantee a component never uses hooks—for example, to keep critical rendering paths side-effect free. If you care about fish—or just deterministic rendering—reach for "use nemo" whenever a component needs to steer clear of hooks.
Caveats
- The directive must be the first statement in the function (comments are allowed above it).
- Hook detection is name-based. Anything starting with
usefollowed by an uppercase letter is treated as a Hook call. - The directive applies to the entire function scope, including nested helper functions declared inside.
"use nemo"and"use memo"are mutually exclusive—if both appear, the compiler reports a conflict.- Module-level directives cascade: a file-level
"use nemo"applies to every function unless a function-level directive overrides it.
How "use nemo" enforces hook bans
The React Compiler performs a static scan for Hook-like calls during compilation. With "use nemo" active:
- Direct imports from
reactsuch asuseState,useEffect, oruseContextcause a compile-time error. - Custom helpers named like Hooks (
useAnalytics,useFishTank, etc.) are also blocked. - The compiler suggests moving Hook logic into a different component or converting it into a prop-driven API.
This safeguard is handy when migrating legacy class components or when you need deterministic rendering behavior without Hook scheduling. Just like Nemo dodging fishing hooks, components guarded by "use nemo" stay clear of hook-induced side effects.
When to use "use nemo"
"use nemo" is primarily suited for:
Critical rendering paths
Performance-sensitive sections that must avoid Hook re-execution can opt into "use nemo" to guarantee purity.
function CriticalPromo({ promo }) {
"use nemo";
// ✅ Everything here must be pure computations.
return <Hero banner={computeBanner(promo)} />;
}Enforcing architectural boundaries
Large apps sometimes need to restrict Hooks to a specific layer (for example, container vs. presentational components). "use nemo" provides a compile-time guard:
function ButtonView(props) {
"use nemo"; // Presentation-only components stay hook-free.
return <button {...props} />;
}Usage
You can place "use nemo" at either the module or function level:
"use nemo"; // Module-level guard—applies to every function below.
function Wrapper(props) {
return <PureChild {...props} />;
}
function PureChild({ label }) {
"use nemo"; // Optional reinforcement at the function level
return <span>{label}</span>;
}Attempting to call a Hook inside the guarded scope throws a compile-time error:
function Cheater() {
"use nemo";
const [state, setState] = useState(); // ❌ Compiler error: Hooks are forbidden by "use nemo".
return <span>{state}</span>;
}When in doubt, channel Nemo’s survival instincts—if a line smells like bait (anything named useSomething), keep it out of the function.
Troubleshooting
Hook still compiles
If a Hook call slips through, check the directive placement:
function Oops() {
console.log("setup"); // ❌ Directive must come first.
"use nemo";
useEffect(() => {}); // Compiler only sees the directive after the hook.
}Also verify the file isn’t compiled in legacy or experimental modes that skip directive checks.
False positives on helper names
Helpers that start with use and a capital letter count as Hooks. Rename helpers or wrap them:
function useFilter(data) { /* ... */ } // ❌ Looks like a Hook.
function filterData(data) { /* ... */ } // ✅ Rename to avoid the guard.See also
"use memo"- Opt into compilation"use no memo"- Opt out of compilation