Skip to content

Commit 23aa570

Browse files
committed
Add "use nemo"
Vox Populi, Vox Dei
1 parent 2c7798d commit 23aa570

File tree

4 files changed

+154
-1
lines changed

4 files changed

+154
-1
lines changed
4.58 MB
Loading

src/content/reference/react-compiler/directives.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ React Compiler directives provide fine-grained control over which functions are
2424
### Available directives {/*available-directives*/}
2525

2626
* **[`"use memo"`](/reference/react-compiler/directives/use-memo)** - Opts a function into compilation
27+
* **[`"use nemo"`](/reference/react-compiler/directives/use-nemo)** - Blocks Hooks inside the function
2728
* **[`"use no memo"`](/reference/react-compiler/directives/use-no-memo)** - Opts a function out of compilation
2829

2930
### Quick comparison {/*quick-comparison*/}
3031

3132
| Directive | Purpose | When to use |
3233
|-----------|---------|-------------|
3334
| [`"use memo"`](/reference/react-compiler/directives/use-memo) | Force compilation | When using `annotation` mode or to override `infer` mode heuristics |
35+
| [`"use nemo"`](/reference/react-compiler/directives/use-nemo) | Forbid Hooks | Enforcing hook-free components or critical render paths |
3436
| [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) | Prevent compilation | Debugging issues or working with incompatible code |
3537

3638
---
@@ -181,6 +183,7 @@ function ProblematicComponent() {
181183
For specific issues with directives, see the troubleshooting sections in:
182184
183185
* [`"use memo"` troubleshooting](/reference/react-compiler/directives/use-memo#troubleshooting)
186+
* [`"use nemo"` troubleshooting](/reference/react-compiler/directives/use-nemo#troubleshooting)
184187
* [`"use no memo"` troubleshooting](/reference/react-compiler/directives/use-no-memo#troubleshooting)
185188
186189
### Common issues {/*common-issues*/}
@@ -195,4 +198,4 @@ For specific issues with directives, see the troubleshooting sections in:
195198

196199
* [`compilationMode`](/reference/react-compiler/compilationMode) - Configure how the compiler chooses what to optimize
197200
* [`Configuration`](/reference/react-compiler/configuration) - Full compiler configuration options
198-
* [React Compiler documentation](https://react.dev/learn/react-compiler) - Getting started guide
201+
* [React Compiler documentation](https://react.dev/learn/react-compiler) - Getting started guide
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
title: "use nemo"
3+
titleForTitleTag: "'use nemo' directive"
4+
---
5+
6+
<Intro>
7+
8+
`"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.
9+
10+
</Intro>
11+
12+
<InlineToc />
13+
14+
---
15+
16+
## Reference {/*reference*/}
17+
18+
### `"use nemo"` {/*use-nemo*/}
19+
20+
Place `"use nemo"` at the very top of a function body to declare it as a hook-free zone.
21+
22+
```js {1}
23+
function FishFacts() {
24+
"use nemo";
25+
26+
// ✅ Regular code is fine
27+
const [facts] = getFacts(); // Not a Hook, just a regular helper
28+
return <FactsList facts={facts} />;
29+
}
30+
```
31+
32+
![Nemo the clownfish giving a wary look at an unseen fishing hook](/images/docs/use-nemo-directive.png)
33+
34+
*If you care about fish, give them a hook-free habitat.*
35+
36+
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.
37+
38+
#### Caveats {/*caveats*/}
39+
40+
* The directive must be the first statement in the function (comments are allowed above it).
41+
* Hook detection is name-based. Anything starting with `use` followed by an uppercase letter is treated as a Hook call.
42+
* The directive applies to the entire function scope, including nested helper functions declared inside.
43+
* `"use nemo"` and `"use memo"` are mutually exclusive—if both appear, the compiler reports a conflict.
44+
* Module-level directives cascade: a file-level `"use nemo"` applies to every function unless a function-level directive overrides it.
45+
46+
### How `"use nemo"` enforces hook bans {/*how-use-nemo-enforces-hook-bans*/}
47+
48+
The React Compiler performs a static scan for Hook-like calls during compilation. With `"use nemo"` active:
49+
50+
* Direct imports from `react` such as `useState`, `useEffect`, or `useContext` cause a compile-time error.
51+
* Custom helpers named like Hooks (`useAnalytics`, `useFishTank`, etc.) are also blocked.
52+
* The compiler suggests moving Hook logic into a different component or converting it into a prop-driven API.
53+
54+
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.
55+
56+
### When to use `"use nemo"` {/*when-to-use*/}
57+
58+
`"use nemo"` is primarily suited for:
59+
60+
#### Critical rendering paths {/*critical-rendering*/}
61+
Performance-sensitive sections that must avoid Hook re-execution can opt into `"use nemo"` to guarantee purity.
62+
63+
```js
64+
function CriticalPromo({ promo }) {
65+
"use nemo";
66+
67+
// ✅ Everything here must be pure computations.
68+
return <Hero banner={computeBanner(promo)} />;
69+
}
70+
```
71+
72+
#### Enforcing architectural boundaries {/*architectural-boundaries*/}
73+
Large apps sometimes need to restrict Hooks to a specific layer (for example, container vs. presentational components). `"use nemo"` provides a compile-time guard:
74+
75+
```js
76+
function ButtonView(props) {
77+
"use nemo"; // Presentation-only components stay hook-free.
78+
79+
return <button {...props} />;
80+
}
81+
```
82+
83+
---
84+
85+
## Usage {/*usage*/}
86+
87+
You can place `"use nemo"` at either the module or function level:
88+
89+
```js
90+
"use nemo"; // Module-level guard—applies to every function below.
91+
92+
function Wrapper(props) {
93+
return <PureChild {...props} />;
94+
}
95+
96+
function PureChild({ label }) {
97+
"use nemo"; // Optional reinforcement at the function level
98+
return <span>{label}</span>;
99+
}
100+
```
101+
102+
Attempting to call a Hook inside the guarded scope throws a compile-time error:
103+
104+
```js
105+
function Cheater() {
106+
"use nemo";
107+
108+
const [state, setState] = useState(); // ❌ Compiler error: Hooks are forbidden by "use nemo".
109+
return <span>{state}</span>;
110+
}
111+
```
112+
113+
When in doubt, channel Nemo's survival instincts—if a line smells like bait (anything named `useSomething`), keep it out of the function.
114+
115+
---
116+
117+
## Troubleshooting {/*troubleshooting*/}
118+
119+
### Hook still compiles {/*hook-still-compiles*/}
120+
121+
If a Hook call slips through, check the directive placement:
122+
123+
```js
124+
function Oops() {
125+
console.log("setup"); // ❌ Directive must come first.
126+
"use nemo";
127+
useEffect(() => {}); // Compiler only sees the directive after the hook.
128+
}
129+
```
130+
131+
Also verify the file isn’t compiled in `legacy` or experimental modes that skip directive checks.
132+
133+
### False positives on helper names {/*false-positives*/}
134+
135+
Helpers that start with `use` and a capital letter count as Hooks. Rename helpers or wrap them:
136+
137+
```js
138+
function useFilter(data) { /* ... */ } // ❌ Looks like a Hook.
139+
140+
function filterData(data) { /* ... */ } // ✅ Rename to avoid the guard.
141+
```
142+
143+
### See also {/*see-also*/}
144+
145+
* [`"use memo"`](/reference/react-compiler/directives/use-memo) - Opt into compilation
146+
* [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) - Opt out of compilation

src/sidebarReference.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,10 @@
386386
"title": "\"use memo\"",
387387
"path": "/reference/react-compiler/directives/use-memo"
388388
},
389+
{
390+
"title": "\"use nemo\"",
391+
"path": "/reference/react-compiler/directives/use-nemo"
392+
},
389393
{
390394
"title": "\"use no memo\"",
391395
"path": "/reference/react-compiler/directives/use-no-memo"

0 commit comments

Comments
 (0)