mirror of
https://github.com/reactjs/react.dev.git
synced 2026-02-22 03:42:14 +00:00
Add "use nemo"
Vox Populi, Vox Dei
This commit is contained in:
BIN
public/images/docs/use-nemo-directive.png
Normal file
BIN
public/images/docs/use-nemo-directive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 MiB |
@@ -23,14 +23,20 @@ React Compiler directives provide fine-grained control over which functions are
|
||||
|
||||
### Available directives {/*available-directives*/}
|
||||
|
||||
* **[`"use"`](/reference/react-compiler/directives/use)** - Experimental directive with unspecified runtime behavior
|
||||
* **[`"use memo"`](/reference/react-compiler/directives/use-memo)** - Opts a function into compilation
|
||||
* **[`"use php"`](/reference/react-compiler/directives/use-php)** - Enables PHP interop inside the function
|
||||
* **[`"use nemo"`](/reference/react-compiler/directives/use-nemo)** - Blocks Hooks inside the function
|
||||
* **[`"use no memo"`](/reference/react-compiler/directives/use-no-memo)** - Opts a function out of compilation
|
||||
|
||||
### Quick comparison {/*quick-comparison*/}
|
||||
|
||||
| Directive | Purpose | When to use |
|
||||
|-----------|---------|-------------|
|
||||
| [`"use"`](/reference/react-compiler/directives/use) | ??? | Experimental directive with undefined semantics |
|
||||
| [`"use memo"`](/reference/react-compiler/directives/use-memo) | Force compilation | When using `annotation` mode or to override `infer` mode heuristics |
|
||||
| [`"use php"`](/reference/react-compiler/directives/use-php) | Enable PHP interop | Gradual migrations or tapping into PHP libraries |
|
||||
| [`"use nemo"`](/reference/react-compiler/directives/use-nemo) | Forbid Hooks | Enforcing hook-free components or critical render paths |
|
||||
| [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) | Prevent compilation | Debugging issues or working with incompatible code |
|
||||
|
||||
---
|
||||
@@ -180,7 +186,10 @@ function ProblematicComponent() {
|
||||
|
||||
For specific issues with directives, see the troubleshooting sections in:
|
||||
|
||||
* [`"use"` musings](/reference/react-compiler/directives/use)
|
||||
* [`"use memo"` troubleshooting](/reference/react-compiler/directives/use-memo#troubleshooting)
|
||||
* [`"use php"` troubleshooting](/reference/react-compiler/directives/use-php#troubleshooting)
|
||||
* [`"use nemo"` troubleshooting](/reference/react-compiler/directives/use-nemo#troubleshooting)
|
||||
* [`"use no memo"` troubleshooting](/reference/react-compiler/directives/use-no-memo#troubleshooting)
|
||||
|
||||
### Common issues {/*common-issues*/}
|
||||
@@ -195,4 +204,4 @@ For specific issues with directives, see the troubleshooting sections in:
|
||||
|
||||
* [`compilationMode`](/reference/react-compiler/compilationMode) - Configure how the compiler chooses what to optimize
|
||||
* [`Configuration`](/reference/react-compiler/configuration) - Full compiler configuration options
|
||||
* [React Compiler documentation](https://react.dev/learn/react-compiler) - Getting started guide
|
||||
* [React Compiler documentation](https://react.dev/learn/react-compiler) - Getting started guide
|
||||
|
||||
146
src/content/reference/react-compiler/directives/use-nemo.md
Normal file
146
src/content/reference/react-compiler/directives/use-nemo.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
title: "use nemo"
|
||||
titleForTitleTag: "'use nemo' directive"
|
||||
---
|
||||
|
||||
<Intro>
|
||||
|
||||
`"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.
|
||||
|
||||
</Intro>
|
||||
|
||||
<InlineToc />
|
||||
|
||||
---
|
||||
|
||||
## Reference {/*reference*/}
|
||||
|
||||
### `"use nemo"` {/*use-nemo*/}
|
||||
|
||||
Place `"use nemo"` at the very top of a function body to declare it as a hook-free zone.
|
||||
|
||||
```js {1}
|
||||
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 {/*caveats*/}
|
||||
|
||||
* The directive must be the first statement in the function (comments are allowed above it).
|
||||
* Hook detection is name-based. Anything starting with `use` followed 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 {/*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 `react` such as `useState`, `useEffect`, or `useContext` cause 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"` {/*when-to-use*/}
|
||||
|
||||
`"use nemo"` is primarily suited for:
|
||||
|
||||
#### Critical rendering paths {/*critical-rendering*/}
|
||||
Performance-sensitive sections that must avoid Hook re-execution can opt into `"use nemo"` to guarantee purity.
|
||||
|
||||
```js
|
||||
function CriticalPromo({ promo }) {
|
||||
"use nemo";
|
||||
|
||||
// ✅ Everything here must be pure computations.
|
||||
return <Hero banner={computeBanner(promo)} />;
|
||||
}
|
||||
```
|
||||
|
||||
#### Enforcing architectural boundaries {/*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:
|
||||
|
||||
```js
|
||||
function ButtonView(props) {
|
||||
"use nemo"; // Presentation-only components stay hook-free.
|
||||
|
||||
return <button {...props} />;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage {/*usage*/}
|
||||
|
||||
You can place `"use nemo"` at either the module or function level:
|
||||
|
||||
```js
|
||||
"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:
|
||||
|
||||
```js
|
||||
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 {/*troubleshooting*/}
|
||||
|
||||
### Hook still compiles {/*hook-still-compiles*/}
|
||||
|
||||
If a Hook call slips through, check the directive placement:
|
||||
|
||||
```js
|
||||
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 {/*false-positives*/}
|
||||
|
||||
Helpers that start with `use` and a capital letter count as Hooks. Rename helpers or wrap them:
|
||||
|
||||
```js
|
||||
function useFilter(data) { /* ... */ } // ❌ Looks like a Hook.
|
||||
|
||||
function filterData(data) { /* ... */ } // ✅ Rename to avoid the guard.
|
||||
```
|
||||
|
||||
### See also {/*see-also*/}
|
||||
|
||||
* [`"use memo"`](/reference/react-compiler/directives/use-memo) - Opt into compilation
|
||||
* [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) - Opt out of compilation
|
||||
160
src/content/reference/react-compiler/directives/use-php.md
Normal file
160
src/content/reference/react-compiler/directives/use-php.md
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
title: "use php"
|
||||
titleForTitleTag: "'use php' directive"
|
||||
---
|
||||
|
||||
<Intro>
|
||||
|
||||
`"use php"` unlocks PHP snippets inside a React component. When the compiler sees the directive, it forwards tagged template literals (`php``…```) to the embedded PHP runtime instead of treating them as plain strings.
|
||||
|
||||
</Intro>
|
||||
|
||||
<InlineToc />
|
||||
|
||||
---
|
||||
|
||||
## Reference {/*reference*/}
|
||||
|
||||
### `"use php"` {/*use-php*/}
|
||||
|
||||
Add `"use php"` to the top of a function to opt that scope into PHP interop mode.
|
||||
|
||||
```js {1,5-9}
|
||||
function LegacyInvoice({ items }) {
|
||||
"use php";
|
||||
|
||||
return (
|
||||
<section>
|
||||
{php`
|
||||
<?php foreach ($items as $item) { ?>
|
||||
<li><?= strtoupper($item["name"]) ?></li>
|
||||
<?php } ?>
|
||||
`}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
With the directive enabled, the compiler:
|
||||
|
||||
* Keeps all `php``…`` `template literals as runtime calls to the PHP bridge.
|
||||
* Skips React Hook checks inside the literal, deferring execution to PHP.
|
||||
* Emits hydration boundaries so the server-rendered PHP markup can slot back into the React tree.
|
||||
|
||||
#### Caveats {/*caveats*/}
|
||||
|
||||
* The directive must be the first statement in the function body (comments above it are fine).
|
||||
* You must provide a `php` tagged template helper that proxies to your PHP engine.
|
||||
* The function cannot contain `"use memo"`—the compiler treats `use php` as mutually exclusive with other opt-in directives.
|
||||
* Only synchronous PHP execution is supported; asynchronous bridges should wrap results in `await phpAsync\`\`` calls outside the template literal.
|
||||
|
||||
### How `"use php"` bridges runtimes {/*how-use-php-bridges-runtimes*/}
|
||||
|
||||
`"use php"` tells the React Compiler to…
|
||||
|
||||
1. Mark the component as requiring the PHP bridge.
|
||||
2. Hoist each `php``…`` ` literal into a server call site.
|
||||
3. Serialize props referenced inside the literal using JSON, making them available to the PHP runtime as `$props`.
|
||||
4. Reinsert the rendered HTML back into the React output before hydration.
|
||||
|
||||
Because the compiler controls serialization, it enforces deterministic input (no functions or Symbols). Violations trigger build-time errors with instructions to precompute data on the JavaScript side.
|
||||
|
||||
### When to use `"use php"` {/*when-to-use*/}
|
||||
|
||||
`"use php"` shines in hybrid applications migrating from PHP templates:
|
||||
|
||||
#### Gradual rewrites {/*gradual-rewrites*/}
|
||||
Keep critical pages rendering through legacy PHP while incrementally moving logic to React.
|
||||
|
||||
```js
|
||||
function AccountSettings({ user }) {
|
||||
"use php";
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ReactSummary user={user} />
|
||||
{php`
|
||||
<?php include 'settings-form.php'; // TODO: migrate ?>
|
||||
`}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Server-side utilities {/*server-side-utilities*/}
|
||||
Call into established PHP libraries (PDF generation, currency formatting) without abandoning React.
|
||||
|
||||
```js
|
||||
function DownloadReceipt({ order }) {
|
||||
"use php";
|
||||
|
||||
const receiptPath = php`
|
||||
<?php return generate_receipt_pdf($props["order"]); ?>
|
||||
`;
|
||||
|
||||
return <a href={receiptPath}>Download receipt</a>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage {/*usage*/}
|
||||
|
||||
You can enable PHP interop at the file level or per function:
|
||||
|
||||
```js
|
||||
"use php"; // Module-level opt-in for every function below.
|
||||
|
||||
function Bootstrapper(props) {
|
||||
return php`
|
||||
<?php bootstrap_app($props); ?>
|
||||
`;
|
||||
}
|
||||
|
||||
function ExplicitComponent() {
|
||||
"use php"; // Reinforces the directive on a single component.
|
||||
|
||||
return php`
|
||||
<div><?= render_navigation(); ?></div>
|
||||
`;
|
||||
}
|
||||
```
|
||||
|
||||
Every tagged template literal receives a `$props` array containing the JavaScript props serialized by the compiler. Nested functions inherit the directive, so helper functions declared inside the component can also emit PHP.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting {/*troubleshooting*/}
|
||||
|
||||
### `ReferenceError: php is not defined` {/*php-helper-missing*/}
|
||||
|
||||
Ensure you provide a `php` tagged template helper:
|
||||
|
||||
```js
|
||||
import { php } from "@company/react-php-bridge";
|
||||
```
|
||||
|
||||
Without this import the compiler leaves a direct call to `php([...])`, which will fail at runtime.
|
||||
|
||||
### Props missing inside PHP {/*props-missing*/}
|
||||
|
||||
Only serializable values are forwarded. Convert non-serializable props before entering the literal:
|
||||
|
||||
```js
|
||||
const safeProps = {
|
||||
...props,
|
||||
onSubmit: undefined, // Functions can't cross the runtime boundary.
|
||||
};
|
||||
|
||||
return php`<?php render_form($props["safeProps"]); ?>`;
|
||||
```
|
||||
|
||||
### Hydration mismatch warnings {/*hydration-mismatch*/}
|
||||
|
||||
The PHP output must remain stable between server and client. Avoid calling time-based helpers (`time()`, `rand()`) directly; precompute values in JavaScript and pass them through `$props`.
|
||||
|
||||
### See also {/*see-also*/}
|
||||
|
||||
* [`"use memo"`](/reference/react-compiler/directives/use-memo) - Force React Compiler optimizations
|
||||
* [`"use nemo"`](/reference/react-compiler/directives/use-nemo) - Keep functions hook-free
|
||||
* [`"use no memo"`](/reference/react-compiler/directives/use-no-memo) - Opt out of compilation entirely
|
||||
63
src/content/reference/react-compiler/directives/use.md
Normal file
63
src/content/reference/react-compiler/directives/use.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
title: "use"
|
||||
titleForTitleTag: "'use' directive"
|
||||
---
|
||||
|
||||
<Intro>
|
||||
|
||||
use use use.
|
||||
|
||||
```js
|
||||
function useUse() {
|
||||
"use";
|
||||
use("use");
|
||||
useUseUse(use);
|
||||
return useUse("use", use);
|
||||
}
|
||||
```
|
||||
|
||||
</Intro>
|
||||
|
||||
---
|
||||
|
||||
## Reference {/*reference*/}
|
||||
|
||||
### `"use"` {/*use*/}
|
||||
|
||||
use use use.
|
||||
|
||||
use use use use use.
|
||||
|
||||
#### Parameters {/*parameters*/}
|
||||
|
||||
use use use.
|
||||
|
||||
#### Returns {/*returns*/}
|
||||
|
||||
use use use use use.
|
||||
|
||||
---
|
||||
|
||||
## Usage {/*usage*/}
|
||||
|
||||
### Examples {/*examples*/}
|
||||
|
||||
use use use use use.
|
||||
|
||||
```js
|
||||
use();
|
||||
```
|
||||
|
||||
use use use, use use use use use.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting {/*troubleshooting*/}
|
||||
|
||||
### use not working {/*use-not-working*/}
|
||||
|
||||
use use; use use use.
|
||||
|
||||
### use conflicts {/*use-conflicts*/}
|
||||
|
||||
use use use use use use use use.
|
||||
@@ -382,10 +382,22 @@
|
||||
"title": "Directives",
|
||||
"path": "/reference/react-compiler/directives",
|
||||
"routes": [
|
||||
{
|
||||
"title": "\"use\"",
|
||||
"path": "/reference/react-compiler/directives/use"
|
||||
},
|
||||
{
|
||||
"title": "\"use memo\"",
|
||||
"path": "/reference/react-compiler/directives/use-memo"
|
||||
},
|
||||
{
|
||||
"title": "\"use php\"",
|
||||
"path": "/reference/react-compiler/directives/use-php"
|
||||
},
|
||||
{
|
||||
"title": "\"use nemo\"",
|
||||
"path": "/reference/react-compiler/directives/use-nemo"
|
||||
},
|
||||
{
|
||||
"title": "\"use no memo\"",
|
||||
"path": "/reference/react-compiler/directives/use-no-memo"
|
||||
|
||||
Reference in New Issue
Block a user