diff --git a/.env.production b/.env.production
index d25eb7dd4..e403f96b6 100644
--- a/.env.production
+++ b/.env.production
@@ -1 +1 @@
-NEXT_PUBLIC_GA_TRACKING_ID = 'UA-41298772-4'
\ No newline at end of file
+NEXT_PUBLIC_GA_TRACKING_ID = 'G-B1E83PJ3RT'
\ No newline at end of file
diff --git a/package.json b/package.json
index 472ef79c9..b5e07d70a 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,6 @@
"classnames": "^2.2.6",
"date-fns": "^2.16.1",
"debounce": "^1.2.1",
- "ga-lite": "^2.1.4",
"github-slugger": "^1.3.0",
"next": "^13.4.1",
"next-remote-watch": "^1.0.0",
diff --git a/public/images/docs/diagrams/use_client_module_dependency.dark.png b/public/images/docs/diagrams/use_client_module_dependency.dark.png
new file mode 100644
index 000000000..c50e7308b
Binary files /dev/null and b/public/images/docs/diagrams/use_client_module_dependency.dark.png differ
diff --git a/public/images/docs/diagrams/use_client_module_dependency.png b/public/images/docs/diagrams/use_client_module_dependency.png
new file mode 100644
index 000000000..d535246f7
Binary files /dev/null and b/public/images/docs/diagrams/use_client_module_dependency.png differ
diff --git a/public/images/docs/diagrams/use_client_render_tree.dark.png b/public/images/docs/diagrams/use_client_render_tree.dark.png
new file mode 100644
index 000000000..8d3e6a484
Binary files /dev/null and b/public/images/docs/diagrams/use_client_render_tree.dark.png differ
diff --git a/public/images/docs/diagrams/use_client_render_tree.png b/public/images/docs/diagrams/use_client_render_tree.png
new file mode 100644
index 000000000..ad3840681
Binary files /dev/null and b/public/images/docs/diagrams/use_client_render_tree.png differ
diff --git a/src/components/Layout/Feedback.tsx b/src/components/Layout/Feedback.tsx
index 2bf9afe57..86fc91350 100644
--- a/src/components/Layout/Feedback.tsx
+++ b/src/components/Layout/Feedback.tsx
@@ -4,7 +4,6 @@
import {useState} from 'react';
import {useRouter} from 'next/router';
-import {ga} from '../../utils/analytics';
export function Feedback({onSubmit = () => {}}: {onSubmit?: () => void}) {
const {asPath} = useRouter();
@@ -48,14 +47,12 @@ const thumbsDownIcon = (
function sendGAEvent(isPositive: boolean) {
// Fragile. Don't change unless you've tested the network payload
// and verified that the right events actually show up in GA.
- ga(
- 'send',
- 'event',
- 'button',
- 'feedback',
- window.location.pathname,
- isPositive ? '1' : '0'
- );
+ // @ts-ignore
+ gtag('event', 'feedback', {
+ event_category: 'button',
+ event_label: window.location.pathname,
+ value: isPositive ? 1 : 0,
+ });
}
function SendFeedback({onSubmit}: {onSubmit: () => void}) {
diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx
index fb771f901..04876bab3 100644
--- a/src/components/Layout/Page.tsx
+++ b/src/components/Layout/Page.tsx
@@ -28,7 +28,12 @@ interface PageProps {
children: React.ReactNode;
toc: Array;
routeTree: RouteItem;
- meta: {title?: string; canary?: boolean; description?: string};
+ meta: {
+ title?: string;
+ titleForTitleTag?: string;
+ canary?: boolean;
+ description?: string;
+ };
section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown';
}
@@ -107,6 +112,7 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) {
<>
{
if (lintErrors.length === 0) {
diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx
index 79f19f87c..5af169e13 100644
--- a/src/components/Seo.tsx
+++ b/src/components/Seo.tsx
@@ -9,6 +9,7 @@ import {siteConfig} from '../siteConfig';
export interface SeoProps {
title: string;
+ titleForTitleTag: undefined | string;
description?: string;
image?: string;
// jsonld?: JsonLDType | Array;
@@ -36,7 +37,7 @@ function getDomain(languageCode: string): string {
export const Seo = withRouter(
({
title,
- description = 'The library for web and native user interfaces',
+ titleForTitleTag,
image = '/images/og-default.png',
router,
children,
@@ -47,14 +48,20 @@ export const Seo = withRouter(
const canonicalUrl = `https://${siteDomain}${
router.asPath.split(/[\?\#]/)[0]
}`;
- const pageTitle = isHomePage ? title : title + ' – React';
+ // Allow setting a different title for Google results
+ const pageTitle =
+ (titleForTitleTag ?? title) + (isHomePage ? '' : ' – React');
// Twitter's meta parser is not very good.
const twitterTitle = pageTitle.replace(/[<>]/g, '');
+ let description = isHomePage
+ ? 'React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizations.'
+ : 'The library for web and native user interfaces';
return (
{title != null && {pageTitle}}
- {description != null && (
+ {isHomePage && (
+ // Let Google figure out a good description for each page.
)}
diff --git a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
index a6592fd3b..5071af6ec 100644
--- a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
+++ b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md
@@ -74,7 +74,7 @@ Making plain JavaScript in React components reactive requires a compiler with a
## Offscreen Rendering {/*offscreen-rendering*/}
-Offscreen rendering is an upcoming capability in React for rendering screens in the background without additional performance overhead. You can think of it as a version of the [`content-visiblity` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility) that works not only for DOM elements but React components, too. During our research, we've discovered a variety of use cases:
+Offscreen rendering is an upcoming capability in React for rendering screens in the background without additional performance overhead. You can think of it as a version of the [`content-visibility` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility) that works not only for DOM elements but React components, too. During our research, we've discovered a variety of use cases:
- A router can prerender screens in the background so that when a user navigates to them, they're instantly available.
- A tab switching component can preserve the state of hidden tabs, so the user can switch between them without losing their progress.
diff --git a/src/content/learn/describing-the-ui.md b/src/content/learn/describing-the-ui.md
index e8b6440aa..167fe5b70 100644
--- a/src/content/learn/describing-the-ui.md
+++ b/src/content/learn/describing-the-ui.md
@@ -530,13 +530,21 @@ React uses trees to model the relationships between components and modules.
A React render tree is a representation of the parent and child relationship between components.
-An example React render tree.
+
+
+An example React render tree.
+
+
Components near the top of the tree, near the root component, are considered top-level components. Components with no child components are leaf components. This categorization of components is useful for understanding data flow and rendering performance.
Modelling the relationship between JavaScript modules is another useful way to understand your app. We refer to it as a module dependency tree.
-An example module dependency tree.
+
+
+An example module dependency tree.
+
+
A dependency tree is often used by build tools to bundle all the relevant JavaScript code for the client to download and render. A large bundle size regresses user experience for React apps. Understanding the module dependency tree is helpful to debug such issues.
diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md
index 45c5e77da..31405c0af 100644
--- a/src/content/learn/passing-data-deeply-with-context.md
+++ b/src/content/learn/passing-data-deeply-with-context.md
@@ -985,7 +985,7 @@ export const places = [{
}, {
id: 5,
name: 'Chefchaouen, Marocco',
- description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.',
+ description: 'There are a few theories on why the houses are painted blue, including that the color repels mosquitos or that it symbolizes sky and heaven.',
imageId: 'rTqKo46'
}, {
id: 6,
@@ -1124,7 +1124,7 @@ export const places = [{
}, {
id: 5,
name: 'Chefchaouen, Marocco',
- description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.',
+ description: 'There are a few theories on why the houses are painted blue, including that the color repels mosquitos or that it symbolizes sky and heaven.',
imageId: 'rTqKo46'
}, {
id: 6,
diff --git a/src/content/learn/reacting-to-input-with-state.md b/src/content/learn/reacting-to-input-with-state.md
index 522aa63a1..29f60ca6d 100644
--- a/src/content/learn/reacting-to-input-with-state.md
+++ b/src/content/learn/reacting-to-input-with-state.md
@@ -84,7 +84,7 @@ function submitForm(answer) {
// Pretend it's hitting the network.
return new Promise((resolve, reject) => {
setTimeout(() => {
- if (answer.toLowerCase() == 'istanbul') {
+ if (answer.toLowerCase() === 'istanbul') {
resolve();
} else {
reject(new Error('Good guess but a wrong answer. Try again!'));
diff --git a/src/content/learn/understanding-your-ui-as-a-tree.md b/src/content/learn/understanding-your-ui-as-a-tree.md
index 2a5a24b85..98f60cea8 100644
--- a/src/content/learn/understanding-your-ui-as-a-tree.md
+++ b/src/content/learn/understanding-your-ui-as-a-tree.md
@@ -253,7 +253,7 @@ With conditional rendering, across different renders, the render tree may render
In this example, depending on what `inspiration.type` is, we may render `` or ``. The render tree may be different for each render pass.
-Although render trees may differ across render pases, these trees are generally helpful for identifying what the top-level and leaf components are in a React app. Top-level components are the components nearest to the root component and affect the rendering performance of all the components beneath them and often contain the most complexity. Leaf components are near the bottom of the tree and have no child components and are often frequently re-rendered.
+Although render trees may differ across render passes, these trees are generally helpful for identifying what the *top-level* and *leaf components* are in a React app. Top-level components are the components nearest to the root component and affect the rendering performance of all the components beneath them and often contain the most complexity. Leaf components are near the bottom of the tree and have no child components and are often frequently re-rendered.
Identifying these categories of components are useful for understanding data flow and performance of your app.
diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md
new file mode 100644
index 000000000..dfffc74f5
--- /dev/null
+++ b/src/content/reference/react-dom/components/form.md
@@ -0,0 +1,435 @@
+---
+title: "
` {/*form*/}
+
+To create interactive controls for submitting information, render the [built-in browser `
` supports all [common element props.](/reference/react-dom/components/common#props)
+
+[`action`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#action): a URL or function. When a URL is passed to `action` the form will behave like the HTML form component. When a function is passed to `action` the function will handle the form submission. The function passed to `action` may be async and will be called with a single argument containing the [form data](https://developer.mozilla.org/en-US/docs/Web/API/FormData) of the submitted form. The `action` prop can be overridden by a `formAction` attribute on a `
}
+ >
+
+
+ Search
+
+
+ );
+}
+
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "18.3.0-canary-6db7f4209-20231021",
+ "react-dom": "18.3.0-canary-6db7f4209-20231021",
+ "react-scripts": "^5.0.0",
+ "react-error-boundary": "4.0.3"
+ },
+ "main": "/index.js",
+ "devDependencies": {}
+}
+```
+
+
+
+### Display a form submission error without JavaScript {/*display-a-form-submission-error-without-javascript*/}
+
+Displaying a form submission error message before the JavaScript bundle loads for progressive enhancement requires that:
+
+1. `
` be rendered by a [Server Component](/reference/react/use-client)
+1. the function passed to the `
`'s `action` prop be a [Server Action](/reference/react/use-server)
+1. the `useFormState` Hook be used to display the error message
+
+`useFormState` takes two parameters: a [Server Action](/reference/react/use-server) and an initial state. `useFormState` returns two values, a state variable and an action. The action returned by `useFormState` should be passed to the `action` prop of the form. The state variable returned by `useFormState` can be used to displayed an error message. The value returned by the [Server Action](/reference/react/use-server) passed to `useFormState` will be used to update the state variable.
+
+
+
+```js App.js
+import { useFormState } from "react-dom";
+import { signUpNewUser } from "./api";
+
+export default function Page() {
+ async function signup(prevState, formData) {
+ "use server";
+ const email = formData.get("email");
+ try {
+ await signUpNewUser(email);
+ alert(`Added "${email}"`);
+ } catch (err) {
+ return err.toString();
+ }
+ }
+ const [message, formAction] = useFormState(signup, null);
+ return (
+ <>
+
Signup for my newsletter
+
Signup with the same email twice to see an error
+
+
+
+ Sign up
+ {!!message &&
{message}
}
+
+ >
+ );
+}
+```
+
+```js api.js hidden
+let emails = [];
+
+export async function signUpNewUser(newEmail) {
+ if (emails.includes(newEmail)) {
+ throw new Error("This email address has already been added");
+ }
+ emails.push(newEmail);
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "18.3.0-canary-6db7f4209-20231021",
+ "react-dom": "18.3.0-canary-6db7f4209-20231021",
+ "react-scripts": "^5.0.0"
+ },
+ "main": "/index.js",
+ "devDependencies": {}
+}
+```
+
+
+
+Learn more about updating state from a form action with the [`useFormState`](/reference/react-dom/hooks/useFormState) docs
+
+### Handling multiple submission types {/*handling-multiple-submission-types*/}
+
+Forms can be designed to handle multiple submission actions based on the button pressed by the user. Each button inside a form can be associated with a distinct action or behavior by setting the `formAction` prop.
+
+When a user taps a specific button, the form is submitted, and a corresponding action, defined by that button's attributes and action, is executed. For instance, a form might submit an article for review by default but have a separate button with `formAction` set to save the article as a draft.
+
+
+
+```js App.js
+export default function Search() {
+ function publish(formData) {
+ const content = formData.get("content");
+ const button = formData.get("button");
+ alert(`'${content}' was published with the '${button}' button`);
+ }
+
+ function save(formData) {
+ const content = formData.get("content");
+ alert(`Your draft of '${content}' has been saved!`);
+ }
+
+ return (
+
+
+
+ Publish
+ Save draft
+
+ );
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "18.3.0-canary-6db7f4209-20231021",
+ "react-dom": "18.3.0-canary-6db7f4209-20231021",
+ "react-scripts": "^5.0.0"
+ },
+ "main": "/index.js",
+ "devDependencies": {}
+}
+```
+
+
diff --git a/src/content/reference/react-dom/components/input.md b/src/content/reference/react-dom/components/input.md
index 06010d301..7328fddc9 100644
--- a/src/content/reference/react-dom/components/input.md
+++ b/src/content/reference/react-dom/components/input.md
@@ -32,6 +32,13 @@ To display an input, render the [built-in browser ``](https://developer.m
`` supports all [common element props.](/reference/react-dom/components/common#props)
+
+
+React's extensions to the `formAction` prop are currently only available in React's canary and experimental channels. In stable releases of React `formAction` works only as a [built-in browser HTML component](https://react.dev/reference/react-dom/components#all-html-components). Learn more about [React's release channels here](/community/versioning-policy#all-release-channels).
+
+
+[`formAction`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#formaction): A string or function. Overrides the parent `
` for `type="submit"` and `type="image"`. When a URL is passed to `action` the form will behave like a standard HTML form. When a function is passed to `formAction` the function will handle the form submission. See [`
`](/reference/react-dom/components/form#props).
+
You can [make an input controlled](#controlling-an-input-with-a-state-variable) by passing one of these props:
* [`checked`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement#checked): A boolean. For a checkbox input or a radio button, controls whether it is selected.
diff --git a/src/content/reference/react-dom/hooks/index.md b/src/content/reference/react-dom/hooks/index.md
index 6490dc111..937de808c 100644
--- a/src/content/reference/react-dom/hooks/index.md
+++ b/src/content/reference/react-dom/hooks/index.md
@@ -1,5 +1,5 @@
---
-title: "React DOM Hooks"
+title: "Built-in React DOM Hooks"
---
@@ -21,7 +21,7 @@ Form Hooks are currently only available in React's canary and experimental chann
*Forms* let you create interactive controls for submitting information. To manage forms in your components, use one of these Hooks:
* [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) allows you to make updates to the UI based on the status of the a form.
-* `useFormState` allows you to manage state inside a form.
+* [`useFormState`](/reference/react-dom/hooks/useFormState) allows you to manage state inside a form.
```js
function Form({ action }) {
@@ -46,3 +46,4 @@ function Button() {
);
}
```
+
diff --git a/src/content/reference/react-dom/hooks/useFormState.md b/src/content/reference/react-dom/hooks/useFormState.md
new file mode 100644
index 000000000..53c73ae38
--- /dev/null
+++ b/src/content/reference/react-dom/hooks/useFormState.md
@@ -0,0 +1,291 @@
+---
+title: useFormState
+canary: true
+---
+
+
+
+The `useFormState` Hook is currently only available in React's canary and experimental channels. Learn more about [release channels here](/community/versioning-policy#all-release-channels). In addition, you need to use a framework that supports [React Server Components](/reference/react/use-client) to get the full benefit of `useFormState`.
+
+
+
+
+
+`useFormState` is a Hook that allows you to update state based on the result of a form action.
+
+```js
+const [state, formAction] = useFormState(fn, initialState);
+```
+
+
+
+
+
+---
+
+## Reference {/*reference*/}
+
+### `useFormState(action, initialState)` {/*useformstate*/}
+
+{/* TODO T164397693: link to actions documentation once it exists */}
+
+Call `useFormState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useFormState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided.
+
+```js
+import { useFormState } from "react-dom";
+
+async function increment(previousState, formData) {
+ return previousState + 1;
+}
+
+function StatefulForm({}) {
+ const [state, formAction] = useFormState(increment, 0);
+ return (
+
+ {state}
+ Increment
+
+ )
+}
+```
+
+The form state is the value returned by the action when the form was last submitted. If the form has not yet been submitted, it is the initial state that you pass.
+
+If used with a server action, `useFormState` allows the server's response from submitting the form to be shown even before hydration has completed.
+
+[See more examples below.](#usage)
+
+#### Parameters {/*parameters*/}
+
+* `fn`: The function to be called when the form is submitted or button pressed. When the function is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that a form action normally receives.
+* `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the action is first invoked.
+
+{/* TODO T164397693: link to serializable values docs once it exists */}
+
+#### Returns {/*returns*/}
+
+`useFormState` returns an array with exactly two values:
+
+1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action.
+2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form.
+
+#### Caveats {/*caveats*/}
+
+* When used with a framework that supports React Server Components, `useFormState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, it is equivalent to component local state.
+* The function passed to `useFormState` receives an extra argument, the previous or initial state, as its first argument. This makes its signature different than if it were used directly as a form action without using `useFormState`.
+
+---
+
+## Usage {/*usage*/}
+
+### Using information returned by a form action {/*using-information-returned-by-a-form-action*/}
+
+Call `useFormState` at the top level of your component to access the return value of an action from the last time a form was submitted.
+
+```js [[1, 5, "state"], [2, 5, "formAction"], [3, 5, "action"], [4, 5, "null"], [2, 8, "formAction"]]
+import { useFormState } from 'react-dom';
+import { action } from './actions.js';
+
+function MyComponent() {
+ const [state, formAction] = useFormState(action, null);
+ // ...
+ return (
+
+ {/* ... */}
+
+ );
+}
+```
+
+`useFormState` returns an array with exactly two items:
+
+1. The current state of the form, which is initially set to the initial state you provided, and after the form is submitted is set to the return value of the action you provided.
+2. A new action that you pass to `
` as its `action` prop.
+
+When the form is submitted, the action function that you provided will be called. Its return value will become the new current state of the form.
+
+The action that you provide will also receive a new first argument, namely the current state of the form. The first time the form is submitted, this will be the initial state you provided, while with subsequent submissions, it will be the return value from the last time the action was called. The rest of the arguments are the same as if `useFormState` had not been used
+
+```js [[3, 1, "action"], [1, 1, "currentState"]]
+function action(currentState, formData) {
+ // ...
+ return 'next state';
+}
+```
+
+
+
+#### Display form errors {/*display-form-errors*/}
+
+To display messages such as an error message or toast that's returned by a server action, wrap the action in a call to `useFormState`.
+
+
+
+```js App.js
+import { useState } from "react";
+import { useFormState } from "react-dom";
+import { addToCart } from "./actions.js";
+
+function AddToCartForm({itemID, itemTitle}) {
+ const [message, formAction] = useFormState(addToCart, null);
+ return (
+
+
{itemTitle}
+
+ Add to Cart
+ {message}
+
+ );
+}
+
+export default function App() {
+ return (
+ <>
+
+
+ >
+ )
+}
+```
+
+```js actions.js
+"use server";
+
+export async function addToCart(prevState, queryData) {
+ const itemID = queryData.get('itemID');
+ if (itemID === "1") {
+ return "Added to cart";
+ } else {
+ return "Couldn't add to cart: the item is sold out.";
+ }
+}
+```
+
+```css styles.css hidden
+form {
+ border: solid 1px black;
+ margin-bottom: 24px;
+ padding: 12px
+}
+
+form button {
+ margin-right: 12px;
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "canary",
+ "react-dom": "canary",
+ "react-scripts": "^5.0.0"
+ },
+ "main": "/index.js",
+ "devDependencies": {}
+}
+```
+
+
+
+
+#### Display structured information after submitting a form {/*display-structured-information-after-submitting-a-form*/}
+
+The return value from a server action can be any serializable value. For example, it could be an object that includes a boolean indicating whether the action was successful, an error message, or updated information.
+
+
+
+```js App.js
+import { useState } from "react";
+import { useFormState } from "react-dom";
+import { addToCart } from "./actions.js";
+
+function AddToCartForm({itemID, itemTitle}) {
+ const [formState, formAction] = useFormState(addToCart, {});
+ return (
+
+
{itemTitle}
+
+ Add to Cart
+ {formState?.success &&
+
+ Added to cart! Your cart now has {formState.cartSize} items.
+
+ }
+ {formState?.success === false &&
+
+ Failed to add to cart: {formState.message}
+
+ }
+
+ );
+}
+
+export default function App() {
+ return (
+ <>
+
+
+ >
+ )
+}
+```
+
+```js actions.js
+"use server";
+
+export async function addToCart(prevState, queryData) {
+ const itemID = queryData.get('itemID');
+ if (itemID === "1") {
+ return {
+ success: true,
+ cartSize: 12,
+ };
+ } else {
+ return {
+ success: false,
+ message: "The item is sold out.",
+ };
+ }
+}
+```
+
+```css styles.css hidden
+form {
+ border: solid 1px black;
+ margin-bottom: 24px;
+ padding: 12px
+}
+
+form button {
+ margin-right: 12px;
+}
+```
+
+```json package.json hidden
+{
+ "dependencies": {
+ "react": "canary",
+ "react-dom": "canary",
+ "react-scripts": "^5.0.0"
+ },
+ "main": "/index.js",
+ "devDependencies": {}
+}
+```
+
+
+
+
+
+
+## Troubleshooting {/*troubleshooting*/}
+
+### My action can no longer read the submitted form data {/*my-action-can-no-longer-read-the-submitted-form-data*/}
+
+When you wrap an action with `useFormState`, it gets an extra argument *as its first argument*. The submitted form data is therefore its *second* argument instead of its first as it would usually be. The new first argument that gets added is the current state of the form.
+
+```js
+function action(currentState, formData) {
+ // ...
+}
+```
diff --git a/src/content/reference/react-dom/server/renderToPipeableStream.md b/src/content/reference/react-dom/server/renderToPipeableStream.md
index 26422f185..20a5960eb 100644
--- a/src/content/reference/react-dom/server/renderToPipeableStream.md
+++ b/src/content/reference/react-dom/server/renderToPipeableStream.md
@@ -431,7 +431,7 @@ function ProfilePage() {
}
```
-If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-server-only-content)
+If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)
1. It will emit the loading fallback for the closest `` boundary (`PostsGlimmer`) into the HTML.
2. It will "give up" on trying to render the `Posts` content on the server anymore.
diff --git a/src/content/reference/react-dom/server/renderToReadableStream.md b/src/content/reference/react-dom/server/renderToReadableStream.md
index f4ed54ce2..f407f2245 100644
--- a/src/content/reference/react-dom/server/renderToReadableStream.md
+++ b/src/content/reference/react-dom/server/renderToReadableStream.md
@@ -435,7 +435,7 @@ function ProfilePage() {
}
```
-If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-server-only-content)
+If an error happens in the `Posts` component or somewhere inside it, React will [try to recover from it:](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content)
1. It will emit the loading fallback for the closest `` boundary (`PostsGlimmer`) into the HTML.
2. It will "give up" on trying to render the `Posts` content on the server anymore.
diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md
index 6174cd753..f8884608b 100644
--- a/src/content/reference/react/Component.md
+++ b/src/content/reference/react/Component.md
@@ -632,7 +632,7 @@ class Form extends Component {
return (
<>
-
Hello, {this.state.name}.
+
Hello, {this.state.name}.
>
);
}
diff --git a/src/content/reference/react/cache.md b/src/content/reference/react/cache.md
index 65d95ab76..735560636 100644
--- a/src/content/reference/react/cache.md
+++ b/src/content/reference/react/cache.md
@@ -309,7 +309,7 @@ async function DemoProfile() {
React only provides cache access to the memoized function in a component. When calling `getUser` outside of a component, it will still evaluate the function but not read or update the cache.
-This is because cache access is provided through a [context](/learn/passing-data-deeply-with-context) which is only accessibile from a component.
+This is because cache access is provided through a [context](/learn/passing-data-deeply-with-context) which is only accessible from a component.
diff --git a/src/content/reference/react/directives.md b/src/content/reference/react/directives.md
index b323dab1d..4854310b3 100644
--- a/src/content/reference/react/directives.md
+++ b/src/content/reference/react/directives.md
@@ -19,5 +19,5 @@ Directives provide instructions to [bundlers compatible with React Server Compon
## Source code directives {/*source-code-directives*/}
-* [`'use client'`](/reference/react/use-client) marks source files whose components execute on the client.
+* [`'use client'`](/reference/react/use-client) lets you mark what code runs on the client.
* [`'use server'`](/reference/react/use-server) marks server-side functions that can be called from client-side code.
\ No newline at end of file
diff --git a/src/content/reference/react/experimental_taintObjectReference.md b/src/content/reference/react/experimental_taintObjectReference.md
index e3fd35a48..335f659c6 100644
--- a/src/content/reference/react/experimental_taintObjectReference.md
+++ b/src/content/reference/react/experimental_taintObjectReference.md
@@ -64,7 +64,7 @@ experimental_taintObjectReference(
#### Caveats {/*caveats*/}
-- Recreating or cloning a tainted object creates a new untained object which main contain sensetive data. For example, if you have a tainted `user` object, `const userInfo = {name: user.name, ssn: user.ssn}` or `{...user}` will create new objects which are not tainted. `taintObjectReference` only protects against simple mistakes when the object is passed through to a Client Component unchanged.
+- Recreating or cloning a tainted object creates a new untained object which may contain sensitive data. For example, if you have a tainted `user` object, `const userInfo = {name: user.name, ssn: user.ssn}` or `{...user}` will create new objects which are not tainted. `taintObjectReference` only protects against simple mistakes when the object is passed through to a Client Component unchanged.
@@ -78,7 +78,7 @@ experimental_taintObjectReference(
### Prevent user data from unintentionally reaching the client {/*prevent-user-data-from-unintentionally-reaching-the-client*/}
-A Client Component should never accept objects that carry sensitive data. Ideally, the data fetching functions should not expose data that the current user should not have access to. Sometimes mistakes happen during refactoring. To protect against this mistakes happening down the line we can "taint" the user object in our data API.
+A Client Component should never accept objects that carry sensitive data. Ideally, the data fetching functions should not expose data that the current user should not have access to. Sometimes mistakes happen during refactoring. To protect against these mistakes happening down the line we can "taint" the user object in our data API.
```js
import {experimental_taintObjectReference} from 'react';
diff --git a/src/content/reference/react/experimental_taintUniqueValue.md b/src/content/reference/react/experimental_taintUniqueValue.md
index a67eebf77..e8226d92f 100644
--- a/src/content/reference/react/experimental_taintUniqueValue.md
+++ b/src/content/reference/react/experimental_taintUniqueValue.md
@@ -67,7 +67,8 @@ experimental_taintUniqueValue(
#### Caveats {/*caveats*/}
-- Deriving new values from tainted values can compromise tainting protection. New values created by uppercasing tainted values, concatenating tainted string values into a larger string, converting tainted values to base64, substringing tainted values, and other similar transformations are not tainted unless you explicity call `taintUniqueValue` on these newly created values.
+* Deriving new values from tainted values can compromise tainting protection. New values created by uppercasing tainted values, concatenating tainted string values into a larger string, converting tainted values to base64, substringing tainted values, and other similar transformations are not tainted unless you explicitly call `taintUniqueValue` on these newly created values.
+* Do not use `taintUniqueValue` to protect low-entropy values such as PIN codes or phone numbers. If any value in a request is controlled by an attacker, they could infer which value is tainted by enumerating all possible values of the secret.
---
@@ -130,7 +131,7 @@ In this example, the constant `password` is tainted. Then `password` is used to
Other similar ways of deriving new values from tainted values like concatenating it into a larger string, converting it to base64, or returning a substring create untained values.
-Tainting only protects against simple mistakes like explictly passing secret values to the client. Mistakes in calling the `taintUniqueValue` like using a global store outside of React, without the corresponding lifetime object, can cause the tainted value to become untainted. Tainting is a layer of protection; a secure app will have multiple layers of protection, well designed APIs, and isolation patterns.
+Tainting only protects against simple mistakes like explicitly passing secret values to the client. Mistakes in calling the `taintUniqueValue` like using a global store outside of React, without the corresponding lifetime object, can cause the tainted value to become untainted. Tainting is a layer of protection; a secure app will have multiple layers of protection, well designed APIs, and isolation patterns.
diff --git a/src/content/reference/react/hooks.md b/src/content/reference/react/hooks.md
new file mode 100644
index 000000000..cec71ce8f
--- /dev/null
+++ b/src/content/reference/react/hooks.md
@@ -0,0 +1,139 @@
+---
+title: "Built-in React Hooks"
+---
+
+
+
+*Hooks* let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.
+
+
+
+---
+
+## State Hooks {/*state-hooks*/}
+
+*State* lets a component ["remember" information like user input.](/learn/state-a-components-memory) For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.
+
+To add state to a component, use one of these Hooks:
+
+* [`useState`](/reference/react/useState) declares a state variable that you can update directly.
+* [`useReducer`](/reference/react/useReducer) declares a state variable with the update logic inside a [reducer function.](/learn/extracting-state-logic-into-a-reducer)
+
+```js
+function ImageGallery() {
+ const [index, setIndex] = useState(0);
+ // ...
+```
+
+---
+
+## Context Hooks {/*context-hooks*/}
+
+*Context* lets a component [receive information from distant parents without passing it as props.](/learn/passing-props-to-a-component) For example, your app's top-level component can pass the current UI theme to all components below, no matter how deep.
+
+* [`useContext`](/reference/react/useContext) reads and subscribes to a context.
+
+```js
+function Button() {
+ const theme = useContext(ThemeContext);
+ // ...
+```
+
+---
+
+## Ref Hooks {/*ref-hooks*/}
+
+*Refs* let a component [hold some information that isn't used for rendering,](/learn/referencing-values-with-refs) like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an "escape hatch" from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.
+
+* [`useRef`](/reference/react/useRef) declares a ref. You can hold any value in it, but most often it's used to hold a DOM node.
+* [`useImperativeHandle`](/reference/react/useImperativeHandle) lets you customize the ref exposed by your component. This is rarely used.
+
+```js
+function Form() {
+ const inputRef = useRef(null);
+ // ...
+```
+
+---
+
+## Effect Hooks {/*effect-hooks*/}
+
+*Effects* let a component [connect to and synchronize with external systems.](/learn/synchronizing-with-effects) This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and other non-React code.
+
+* [`useEffect`](/reference/react/useEffect) connects a component to an external system.
+
+```js
+function ChatRoom({ roomId }) {
+ useEffect(() => {
+ const connection = createConnection(roomId);
+ connection.connect();
+ return () => connection.disconnect();
+ }, [roomId]);
+ // ...
+```
+
+Effects are an "escape hatch" from the React paradigm. Don't use Effects to orchestrate the data flow of your application. If you're not interacting with an external system, [you might not need an Effect.](/learn/you-might-not-need-an-effect)
+
+There are two rarely used variations of `useEffect` with differences in timing:
+
+* [`useLayoutEffect`](/reference/react/useLayoutEffect) fires before the browser repaints the screen. You can measure layout here.
+* [`useInsertionEffect`](/reference/react/useInsertionEffect) fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.
+
+---
+
+## Performance Hooks {/*performance-hooks*/}
+
+A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.
+
+To skip calculations and unnecessary re-rendering, use one of these Hooks:
+
+- [`useMemo`](/reference/react/useMemo) lets you cache the result of an expensive calculation.
+- [`useCallback`](/reference/react/useCallback) lets you cache a function definition before passing it down to an optimized component.
+
+```js
+function TodoList({ todos, tab, theme }) {
+ const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
+ // ...
+}
+```
+
+Sometimes, you can't skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don't need to block the user interface (like updating a chart).
+
+To prioritize rendering, use one of these Hooks:
+
+- [`useTransition`](/reference/react/useTransition) lets you mark a state transition as non-blocking and allow other updates to interrupt it.
+- [`useDeferredValue`](/reference/react/useDeferredValue) lets you defer updating a non-critical part of the UI and let other parts update first.
+
+---
+
+## Resource Hooks {/*resource-hooks*/}
+
+*Resources* can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.
+
+To read a value from a resource, use this Hook:
+
+- [`use`](/reference/react/use) lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).
+
+```js
+function MessageComponent({ messagePromise }) {
+ const message = use(messagePromise);
+ const theme = use(ThemeContext);
+ // ...
+}
+```
+
+---
+
+## Other Hooks {/*other-hooks*/}
+
+These Hooks are mostly useful to library authors and aren't commonly used in the application code.
+
+- [`useDebugValue`](/reference/react/useDebugValue) lets you customize the label React DevTools displays for your custom Hook.
+- [`useId`](/reference/react/useId) lets a component associate a unique ID with itself. Typically used with accessibility APIs.
+- [`useSyncExternalStore`](/reference/react/useSyncExternalStore) lets a component subscribe to an external store.
+
+---
+
+## Your own Hooks {/*your-own-hooks*/}
+
+You can also [define your own custom Hooks](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component) as JavaScript functions.
diff --git a/src/content/reference/react/index.md b/src/content/reference/react/index.md
index cec71ce8f..452f326d2 100644
--- a/src/content/reference/react/index.md
+++ b/src/content/reference/react/index.md
@@ -1,139 +1,30 @@
---
-title: "Built-in React Hooks"
+title: React Reference Overview
---
-
-*Hooks* let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.
-
+This section provides detailed reference documentation for working with React.
+For an introduction to React, please visit the [Learn](/learn) section.
----
-
-## State Hooks {/*state-hooks*/}
-
-*State* lets a component ["remember" information like user input.](/learn/state-a-components-memory) For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.
-
-To add state to a component, use one of these Hooks:
-
-* [`useState`](/reference/react/useState) declares a state variable that you can update directly.
-* [`useReducer`](/reference/react/useReducer) declares a state variable with the update logic inside a [reducer function.](/learn/extracting-state-logic-into-a-reducer)
-
-```js
-function ImageGallery() {
- const [index, setIndex] = useState(0);
- // ...
-```
-
----
-
-## Context Hooks {/*context-hooks*/}
-
-*Context* lets a component [receive information from distant parents without passing it as props.](/learn/passing-props-to-a-component) For example, your app's top-level component can pass the current UI theme to all components below, no matter how deep.
-
-* [`useContext`](/reference/react/useContext) reads and subscribes to a context.
-
-```js
-function Button() {
- const theme = useContext(ThemeContext);
- // ...
-```
-
----
-
-## Ref Hooks {/*ref-hooks*/}
-
-*Refs* let a component [hold some information that isn't used for rendering,](/learn/referencing-values-with-refs) like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an "escape hatch" from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.
-
-* [`useRef`](/reference/react/useRef) declares a ref. You can hold any value in it, but most often it's used to hold a DOM node.
-* [`useImperativeHandle`](/reference/react/useImperativeHandle) lets you customize the ref exposed by your component. This is rarely used.
-
-```js
-function Form() {
- const inputRef = useRef(null);
- // ...
-```
-
----
-
-## Effect Hooks {/*effect-hooks*/}
-
-*Effects* let a component [connect to and synchronize with external systems.](/learn/synchronizing-with-effects) This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and other non-React code.
-
-* [`useEffect`](/reference/react/useEffect) connects a component to an external system.
-
-```js
-function ChatRoom({ roomId }) {
- useEffect(() => {
- const connection = createConnection(roomId);
- connection.connect();
- return () => connection.disconnect();
- }, [roomId]);
- // ...
-```
+Our The React reference documentation is broken down into functional subsections:
-Effects are an "escape hatch" from the React paradigm. Don't use Effects to orchestrate the data flow of your application. If you're not interacting with an external system, [you might not need an Effect.](/learn/you-might-not-need-an-effect)
+## React {/*react*/}
+Programmatic React features:
+* [Hooks](/reference/react/hooks) - Use different React features from your components.
+* [Components](/reference/react/components) - Documents built-in components that you can use in your JSX.
+* [APIs](/reference/react/apis) - APIs that are useful for defining components.
+* [Directives](/reference/react/directives) - Provide instructions to bundlers compatible with React Server Components.
-There are two rarely used variations of `useEffect` with differences in timing:
-
-* [`useLayoutEffect`](/reference/react/useLayoutEffect) fires before the browser repaints the screen. You can measure layout here.
-* [`useInsertionEffect`](/reference/react/useInsertionEffect) fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.
-
----
-
-## Performance Hooks {/*performance-hooks*/}
-
-A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.
-
-To skip calculations and unnecessary re-rendering, use one of these Hooks:
-
-- [`useMemo`](/reference/react/useMemo) lets you cache the result of an expensive calculation.
-- [`useCallback`](/reference/react/useCallback) lets you cache a function definition before passing it down to an optimized component.
-
-```js
-function TodoList({ todos, tab, theme }) {
- const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
- // ...
-}
-```
-
-Sometimes, you can't skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don't need to block the user interface (like updating a chart).
-
-To prioritize rendering, use one of these Hooks:
-
-- [`useTransition`](/reference/react/useTransition) lets you mark a state transition as non-blocking and allow other updates to interrupt it.
-- [`useDeferredValue`](/reference/react/useDeferredValue) lets you defer updating a non-critical part of the UI and let other parts update first.
-
----
-
-## Resource Hooks {/*resource-hooks*/}
-
-*Resources* can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.
-
-To read a value from a resource, use this Hook:
-
-- [`use`](/reference/react/use) lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).
-
-```js
-function MessageComponent({ messagePromise }) {
- const message = use(messagePromise);
- const theme = use(ThemeContext);
- // ...
-}
-```
-
----
-
-## Other Hooks {/*other-hooks*/}
-
-These Hooks are mostly useful to library authors and aren't commonly used in the application code.
-
-- [`useDebugValue`](/reference/react/useDebugValue) lets you customize the label React DevTools displays for your custom Hook.
-- [`useId`](/reference/react/useId) lets a component associate a unique ID with itself. Typically used with accessibility APIs.
-- [`useSyncExternalStore`](/reference/react/useSyncExternalStore) lets a component subscribe to an external store.
-
----
+## React DOM {/*react-dom*/}
+React-dom contains features that are only supported for web applications
+(which run in the browser DOM environment). This section is broken into the following:
-## Your own Hooks {/*your-own-hooks*/}
+* [Hooks](/reference/react-dom/hooks) - Hooks for web applications which run in the browser DOM environment.
+* [Components](/reference/react-dom/components) - React supports all of the browser built-in HTML and SVG components.
+* [APIs](/reference/react-dom) - The `react-dom` package contains methods supported only in web applications.
+* [Client APIs](/reference/react-dom/client) - The `react-dom/client` APIs let you render React components on the client (in the browser).
+* [Server APIs](/reference/react-dom/server) - The `react-dom/server` APIs let you render React components to HTML on the server.
-You can also [define your own custom Hooks](/learn/reusing-logic-with-custom-hooks#extracting-your-own-custom-hook-from-a-component) as JavaScript functions.
+## Legacy APIs {/*legacy-apis*/}
+* [Legacy APIs](/reference/react/legacy) - Exported from the react package, but not recommended for use in newly written code.
\ No newline at end of file
diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md
index f0510415b..f4b90d288 100644
--- a/src/content/reference/react/use-client.md
+++ b/src/content/reference/react/use-client.md
@@ -1,5 +1,6 @@
---
title: "'use client'"
+titleForTitleTag: "'use client' directive"
canary: true
---
@@ -11,7 +12,7 @@ canary: true
-`'use client'` marks source files whose components execute on the client.
+`'use client'` lets you mark what code runs on the client.
@@ -23,37 +24,356 @@ canary: true
### `'use client'` {/*use-client*/}
-Add `'use client';` at the very top of a file to mark that the file (including any child components it uses) executes on the client, regardless of where it's imported.
+Add `'use client'` at the top of a file to mark the module and its transitive dependencies as client code.
-```js
+```js {1}
'use client';
import { useState } from 'react';
+import { formatDate } from './formatters';
+import Button from './button';
-export default function RichTextEditor(props) {
+export default function RichTextEditor({ timestamp, text }) {
+ const date = formatDate(timestamp);
+ // ...
+ const editButton = ;
// ...
+}
```
-When a file marked `'use client'` is imported from a server component, [compatible bundlers](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) will treat the import as the "cut-off point" between server-only code and client code. Components at or below this point in the module graph can use client-only React features like [`useState`](/reference/react/useState).
+When a file marked with `'use client'` is imported from a Server Component, [compatible bundlers](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) will treat the module import as a boundary between server-run and client-run code.
+
+As dependencies of `RichTextEditor`, `formatDate` and `Button` will also be evaluated on the client regardless of whether their modules contain a `'use client'` directive. Note that a single module may be evaluated on the server when imported from server code and on the client when imported from client code.
#### Caveats {/*caveats*/}
-* It's not necessary to add `'use client'` to every file that uses client-only React features, only the files that are imported from server component files. `'use client'` denotes the _boundary_ between server-only and client code; any components further down the tree will automatically be executed on the client. In order to be rendered from server components, components exported from `'use client'` files must have serializable props.
-* When a `'use client'` file is imported from a server file, the imported values can be rendered as a React component or passed via props to a client component. Any other use will throw an exception.
-* When a `'use client'` file is imported from another client file, the directive has no effect. This allows you to write client-only components that are simultaneously usable from server and client components.
-* All the code in `'use client'` file as well as any modules it imports (directly or indirectly) will become a part of the client module graph and must be sent to and executed by the client in order to be rendered by the browser. To reduce client bundle size and take full advantage of the server, move state (and the `'use client'` directives) lower in the tree when possible, and pass rendered server components [as children](/learn/passing-props-to-a-component#passing-jsx-as-children) to client components.
-* Because props are serialized across the server–client boundary, note that the placement of these directives can affect the amount of data sent to the client; avoid data structures that are larger than necessary.
-* Components like a `` that use neither server-only nor client-only features should generally not be marked with `'use client'`. That way, they can render exclusively on the server when used from a server component, but they'll be added to the client bundle when used from a client component.
-* Libraries published to npm should include `'use client'` on exported React components that can be rendered with serializable props that use client-only React features, to allow those components to be imported and rendered by server components. Otherwise, users will need to wrap library components in their own `'use client'` files which can be cumbersome and prevents the library from moving logic to the server later. When publishing prebundled files to npm, ensure that `'use client'` source files end up in a bundle marked with `'use client'`, separate from any bundle containing exports that can be used directly on the server.
-* Client components will still run as part of server-side rendering (SSR) or build-time static site generation (SSG), which act as clients to transform React components' initial render output to HTML that can be rendered before JavaScript bundles are downloaded. But they can't use server-only features like reading directly from a database.
-* Directives like `'use client'` must be at the very beginning of a file, above any imports or other code (comments above directives are OK). They must be written with single or double quotes, not backticks. (The `'use xyz'` directive format somewhat resembles the `useXyz()` Hook naming convention, but the similarity is coincidental.)
+* `'use client'` must be at the very beginning of a file, above any imports or other code (comments are OK). They must be written with single or double quotes, but not backticks.
+* When a `'use client'` module is imported from another client-rendered module, the directive has no effect.
+* When a component module contains a `'use client'` directive, any usage of that component is guaranteed to be a Client Component. However, a component can still be evaluated on the client even if it does not have a `'use client'` directive.
+ * A component usage is considered a Client Component if it is defined in module with `'use client'` directive or when it is a transitive dependency of a module that contains a `'use client'` directive. Otherwise, it is a Server Component.
+* Code that is marked for client evaluation is not limited to components. All code that is a part of the client module sub-tree is sent to and run by the client.
+* When a server evaluated module imports values from a `'use client'` module, the values must either be a React component or [supported serializable prop values](#passing-props-from-server-to-client-components) to be passed to a Client Component. Any other use case will throw an exception.
+
+### How `'use client'` marks client code {/*how-use-client-marks-client-code*/}
+
+In a React app, components are often split into separate files, or [modules](/learn/importing-and-exporting-components#exporting-and-importing-a-component).
+
+For apps that use React Server Components, the app is server-rendered by default. `'use client'` introduces a server-client boundary in the [module dependency tree](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree), effectively creating a subtree of client modules.
+
+To better illustrate this, consider the following React Server Components app.
+
+
+
+```js App.js
+import FancyText from './FancyText';
+import InspirationGenerator from './InspirationGenerator';
+import Copyright from './Copyright';
+
+export default function App() {
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
+
+```
+
+```js FancyText.js
+export default function FancyText({title, text}) {
+ return title
+ ?
;
+}
+```
+
+```js inspirations.js
+export default [
+ "Don’t let yesterday take up too much of today.” — Will Rogers",
+ "Ambition is putting a ladder against the sky.",
+ "A joy that's shared is a joy made double.",
+];
+```
+
+```css
+.fancy {
+ font-family: 'Georgia';
+}
+.title {
+ color: #007AA3;
+ text-decoration: underline;
+}
+.cursive {
+ font-style: italic;
+}
+.small {
+ font-size: 10px;
+}
+```
+
+
+
+In the module dependency tree of this example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client modules. The subtree starting at `InspirationGenerator.js` is now marked as client modules.
+
+
+`'use client'` segments the module dependency tree of the React Server Components app, marking `InspirationGenerator.js` and all of its dependencies as client-rendered.
+
+
+During render, the framework will server-render the root component and continue through the [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree), opting-out of evaluating any code imported from client-marked code.
+
+The server-rendered portion of the render tree is then sent to the client. The client, with its client code downloaded, then completes rendering the rest of the tree.
+
+
+The render tree for the React Server Components app. `InspirationGenerator` and its child component `FancyText` are components exported from client-marked code and considered Client Components.
+
+
+We introduce the following definitions:
+
+* **Client Components** are components in a render tree that are rendered on the client.
+* **Server Components** are components in a render tree that are rendered on the server.
+
+Working through the example app, `App`, `FancyText` and `Copyright` are all server-rendered and considered Server Components. As `InspirationGenerator.js` and its transitive dependencies are marked as client code, the component `InspirationGenerator` and its child component `FancyText` are Client Components.
+
+
+#### How is `FancyText` both a Server and a Client Component? {/*how-is-fancytext-both-a-server-and-a-client-component*/}
+
+By the above definitions, the component `FancyText` is both a Server and Client Component, how can that be?
+
+First, let's clarify that the term "component" is not very precise. Here are just two ways "component" can be understood:
+
+1. A "component" can refer to a **component definition**. In most cases this will be a function.
+
+```js
+// This is a definition of a component
+function MyComponent() {
+ return
My Component
+}
+```
+
+2. A "component" can also refer to a **component usage** of its definition.
+```js
+import MyComponent from './MyComponent';
+
+function App() {
+ // This is a usage of a component
+ return ;
+}
+```
+
+Often, the imprecision is not important when explaining concepts, but in this case it is.
+
+When we talk about Server or Client Components, we are referring to component usages.
+
+* If the component is defined in a module with a `'use client'` directive, or the component is imported and called in a Client Component, then the component usage is a Client Component.
+* Otherwise, the component usage is a Server Component.
+
+
+A render tree illustrates component usages.
+
+Back to the question of `FancyText`, we see that the component definition does _not_ have a `'use client'` directive and it has two usages.
+
+The usage of `FancyText` as a child of `App`, marks that usage as a Server Component. When `FancyText` is imported and called under `InspirationGenerator`, that usage of `FancyText` is a Client Component as `InspirationGenerator` contains a `'use client'` directive.
+
+This means that the component definition for `FancyText` will both be evaluated on the server and also downloaded by the client to render its Client Component usage.
+
+
+
+
+
+#### Why is `Copyright` a Server Component? {/*why-is-copyright-a-server-component*/}
+
+Because `Copyright` is rendered as a child of the Client Component `InspirationGenerator`, you might be surprised that it is a Server Component.
+
+Recall that `'use client'` defines the boundary between server and client code on the _module dependency tree_, not the render tree.
+
+
+`'use client'` defines the boundary between server and client code on the module dependency tree.
+
+
+In the module dependency tree, we see that `App.js` imports and calls `Copyright` from the `Copyright.js` module. As `Copyright.js` does not contain a `'use client'` directive, the component usage is rendered on the server. `App` is rendered on the server as it is the root component.
+
+Client Components can render Server Components because you can pass JSX as props. In this case, `InspirationGenerator` receives `Copyright` as [children](/learn/passing-props-to-a-component#passing-jsx-as-children). However, the `InspirationGenerator` module never directly imports the `Copyright` module nor calls the component, all of that is done by `App`. In fact, the `Copyright` component is fully executed before `InspirationGenerator` starts rendering.
+
+The takeaway is that a parent-child render relationship between components does not guarantee the same render environment.
+
+
+
+### When to use `'use client'` {/*when-to-use-use-client*/}
+
+With `'use client'`, you can determine when components are Client Components. As Server Components are default, here is a brief overview of the advantages and limitations to Server Components to determine when you need to mark something as client rendered.
+
+For simplicity, we talk about Server Components, but the same principles apply to all code in your app that is server run.
+
+#### Advantages of Server Components {/*advantages*/}
+* Server Components can reduce the amount of code sent and run by the client. Only client modules are bundled and evaluated by the client.
+* Server Components benefit from running on the server. They can access the local filesystem and may experience low latency for data fetches and network requests.
+
+#### Limitations of Server Components {/*limitations*/}
+* Server Components cannot support interaction as event handlers must be registered and triggered by a client.
+ * For example, event handlers like `onClick` can only be defined in Client Components.
+* Server Components cannot use most Hooks.
+ * When Server Components are rendered, their output is essentially a list of components for the client to render. Server Components do not persist in memory after render and cannot have their own state.
+
+### Serializable types returned by Server Components {/*serializable-types*/}
+
+As in any React app, parent components pass data to child components. As they are rendered in different environments, passing data from a Server Component to a Client Component requires extra consideration.
+
+Prop values passed from a Server Component to Client Component must be serializable.
+
+Serializable props include:
+* Primitives
+ * [string](https://developer.mozilla.org/en-US/docs/Glossary/String)
+ * [number](https://developer.mozilla.org/en-US/docs/Glossary/Number)
+ * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
+ * [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean)
+ * [undefined](https://developer.mozilla.org/en-US/docs/Glossary/Undefined)
+ * [null](https://developer.mozilla.org/en-US/docs/Glossary/Null)
+ * [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), only symbols registered in the global Symbol registry via [`Symbol.for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)
+* Iterables containing serializable values
+ * [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
+ * [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
+ * [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
+ * [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
+ * [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) and [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
+* [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
+* Plain [objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object): those created with [object initializers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer), with serializable properties
+* Functions that are [server actions](/reference/react/use-server)
+* Client or Server Component elements (JSX)
+* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
+
+Notably, these are not supported:
+* [Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) that are not exported from client-marked modules or marked with [`'use server'`](/reference/react/use-server)
+* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript)
+* Objects that are instances of any class (other than the built-ins mentioned) or objects with [a null prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)
+* Symbols not registered globally, ex. `Symbol('my new symbol')`
+
## Usage {/*usage*/}
-
-This section is a work in progress.
+### Building with interactivity and state {/*building-with-interactivity-and-state*/}
+
+
+
+```js App.js
+'use client';
+
+import { useState } from 'react';
+
+export default function Counter({initialValue = 0}) {
+ const [countValue, setCountValue] = useState(initialValue);
+ const increment = () => setCountValue(countValue + 1);
+ const decrement = () => setCountValue(countValue - 1);
+ return (
+ <>
+
Count Value: {countValue}
+ +1
+ -1
+ >
+ );
+}
+```
+
+
+
+As `Counter` requires both the `useState` hook and event handlers to increment or decrement the value, this component must be a Client Component and will require a `'use client'` directive at the top.
+
+In contrast, a component that renders UI without interaction will not need to be a Client Component.
+
+```js
+import { readFile } from 'node:fs/promises';
+import Counter from './Counter';
+
+export default async function CounterContainer() {
+ const initialValue = await readFile('/path/to/counter_value');
+ return
+}
+```
+
+For example, `Counter`'s parent component, `CounterContainer`, does not require `'use client'` as it is not interactive and does not use state. In addition, `CounterContainer` must be a Server Component as it reads from the local file system on the server, which is possible only in a Server Component.
+
+There are also components that don't use any server or client-only features and can be agnostic to where they render. In our earlier example, `FancyText` is one such component.
+
+```js
+export default function FancyText({title, text}) {
+ return title
+ ?
{text}
+ :
{text}
+}
+```
+
+In this case, we don't add the `'use client'` directive, resulting in `FancyText`'s _output_ (rather than its source code) to be sent to the browser when referenced from a Server Component. As demonstrated in the earlier Inspirations app example, `FancyText` is used as both a Server or Client Component, depending on where it is imported and used.
+
+But if `FancyText`'s HTML output was large relative to its source code (including dependencies), it might be more efficient to force it to always be a Client Component. Components that return a long SVG path string are one case where it may be more efficient to force a component to be a Client Component.
+
+### Using client APIs {/*using-client-apis*/}
+
+Your React app may use client-specific APIs, such as the browser's APIs for web storage, audio and video manipulation, and device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API).
+
+In this example, the component uses [DOM APIs](https://developer.mozilla.org/en-US/docs/Glossary/DOM) to manipulate a [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element. Since those APIs are only available in the browser, it must be marked as a Client Component.
+
+```js
+'use client';
+
+import {useRef, useEffect} from 'react';
+
+export default function Circle() {
+ const ref = useRef(null);
+ useLayoutEffect(() => {
+ const canvas = ref.current;
+ const context = canvas.getContext('2d');
+ context.reset();
+ context.beginPath();
+ context.arc(100, 75, 50, 0, 2 * Math.PI);
+ context.stroke();
+ });
+ return ;
+}
+```
+
+### Using third-party libraries {/*using-third-party-libraries*/}
+
+Often in a React app, you'll leverage third-party libraries to handle common UI patterns or logic.
+
+These libraries may rely on component Hooks or client APIs. Third-party components that use any of the following React APIs must run on the client:
+* [createContext](/reference/react/createContext)
+* [`react`](/reference/react/hooks) and [`react-dom`](/reference/react-dom/hooks) Hooks, excluding [`use`](/reference/react/use) and [`useId`](/reference/react/useId)
+* [forwardRef](/reference/react/forwardRef)
+* [memo](/reference/react/memo)
+* [startTransition](/reference/react/startTransition)
+* If they use client APIs, ex. DOM insertion or native platform views
+
+If these libraries have been updated to be compatible with React Server Components, then they will already include `'use client'` markers of their own, allowing you to use them directly from your Server Components. If a library hasn't been updated, or if a component needs props like event handlers that can only be specified on the client, you may need to add your own Client Component file in between the third-party Client Component and your Server Component where you'd like to use it.
-This API can be used in any framework that supports React Server Components. You may find additional documentation from them.
-* [Next.js documentation](https://nextjs.org/docs/getting-started/react-essentials)
-* More coming soon
-
\ No newline at end of file
+[TODO]: <> (Troubleshooting - need use-cases)
\ No newline at end of file
diff --git a/src/content/reference/react/use-server.md b/src/content/reference/react/use-server.md
index 4acea191c..69f5e1044 100644
--- a/src/content/reference/react/use-server.md
+++ b/src/content/reference/react/use-server.md
@@ -1,5 +1,6 @@
---
title: "'use server'"
+titleForTitleTag: "'use server' directive"
canary: true
---
@@ -24,34 +25,191 @@ canary: true
### `'use server'` {/*use-server*/}
-Add `'use server';` at the very top of an async function to mark that the function can be executed by the client.
+Add `'use server'` at the top of an async function body to mark the function as callable by the client. We call these functions _server actions_.
-```js
+```js {2}
async function addToCart(data) {
'use server';
// ...
}
-
-//
```
-This function can be passed to the client. When called on the client, it will make a network request to the server that includes a serialized copy of any arguments passed. If the server function returns a value, that value will be serialized and returned to the client.
+When calling a server action on the client, it will make a network request to the server that includes a serialized copy of any arguments passed. If the server action returns a value, that value will be serialized and returned to the client.
-Alternatively, add `'use server';` at the very top of a file to mark all exports within that file as async server functions that can be used anywhere, including imported in client component files.
+Instead of individually marking functions with `'use server'`, you can add the directive to the top of a file to mark all exports within that file as server actions that can be used anywhere, including imported in client code.
#### Caveats {/*caveats*/}
+* `'use server'` must be at the very beginning of their function or module; above any other code including imports (comments above directives are OK). They must be written with single or double quotes, not backticks.
+* `'use server'` can only be used in server-side files. The resulting server actions can be passed to Client Components through props. See supported [types for serialization](#serializable-parameters-and-return-values).
+* To import a server action from [client code](/reference/react/use-client), the directive must be used on a module level.
+* Because the underlying network calls are always asynchronous, `'use server'` can only be used on async functions.
+* Always treat arguments to server actions as untrusted input and authorize any mutations. See [security considerations](#security).
+* Server actions should be called in a [transition](/reference/react/useTransition). Server actions passed to [`
`](/reference/react-dom/components/form#props) or [`formAction`](/reference/react-dom/components/input#props) will automatically be called in a transition.
+* Server actions are designed for mutations that update server-side state; they are not recommended for data fetching. Accordingly, frameworks implementing server actions typically process one action at a time and do not have a way to cache the return value.
-* Remember that parameters to functions marked with `'use server'` are fully client-controlled. For security, always treat them as untrusted input, making sure to validate and escape the arguments as appropriate.
-* To avoid the confusion that might result from mixing client- and server-side code in the same file, `'use server'` can only be used in server-side files; the resulting functions can be passed to client components through props.
-* Because the underlying network calls are always asynchronous, `'use server'` can be used only on async functions.
-* Directives like `'use server'` must be at the very beginning of their function or file, above any other code including imports (comments above directives are OK). They must be written with single or double quotes, not backticks. (The `'use xyz'` directive format somewhat resembles the `useXyz()` Hook naming convention, but the similarity is coincidental.)
+### Security considerations {/*security*/}
-## Usage {/*usage*/}
+Arguments to server actions are fully client-controlled. For security, always treat them as untrusted input, and make sure to validate and escape arguments as appropriate.
+
+In any server action, make sure to validate that the logged-in user is allowed to perform that action.
-This section is a work in progress.
-This API can be used in any framework that supports React Server Components. You may find additional documentation from them.
-* [Next.js documentation](https://nextjs.org/docs/getting-started/react-essentials)
-* More coming soon
-
\ No newline at end of file
+To prevent sending sensitive data from a server action, there are experimental taint APIs to prevent unique values and objects from being passed to client code.
+
+See [experimental_taintUniqueValue](/reference/react/experimental_taintUniqueValue) and [experimental_taintObjectReference](/reference/react/experimental_taintObjectReference).
+
+
+
+### Serializable arguments and return values {/*serializable-parameters-and-return-values*/}
+
+As client code calls the server action over the network, any arguments passed will need to be serializable.
+
+Here are supported types for server action arguments:
+
+* Primitives
+ * [string](https://developer.mozilla.org/en-US/docs/Glossary/String)
+ * [number](https://developer.mozilla.org/en-US/docs/Glossary/Number)
+ * [bigint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt)
+ * [boolean](https://developer.mozilla.org/en-US/docs/Glossary/Boolean)
+ * [undefined](https://developer.mozilla.org/en-US/docs/Glossary/Undefined)
+ * [null](https://developer.mozilla.org/en-US/docs/Glossary/Null)
+ * [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), only symbols registered in the global Symbol registry via [`Symbol.for`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for)
+* Iterables containing serializable values
+ * [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
+ * [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
+ * [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)
+ * [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
+ * [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) and [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
+* [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
+* [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) instances
+* Plain [objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object): those created with [object initializers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer), with serializable properties
+* Functions that are server actions
+* [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
+
+Notably, these are not supported:
+* React elements, or [JSX](https://react.dev/learn/writing-markup-with-jsx)
+* Functions, including component functions or any other function that is not a server action
+* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript)
+* Objects that are instances of any class (other than the built-ins mentioned) or objects with [a null prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects)
+* Symbols not registered globally, ex. `Symbol('my new symbol')`
+
+
+Supported serializable return values are the same as [serializable props](/reference/react/use-client#passing-props-from-server-to-client-components) for a boundary Client Component.
+
+
+## Usage {/*usage*/}
+
+### Server actions in forms {/*server-actions-in-forms*/}
+
+The most common use case of server actions will be calling server functions that mutate data. On the browser, the [HTML form element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) is the traditional approach for a user to submit a mutation. With React Server Components, React introduces first-class support for server actions in [forms](/reference/react-dom/components/form).
+
+Here is a form that allows a user to request a username.
+
+```js [[1, 3, "formData"]]
+// App.js
+
+async function requestUsername(formData) {
+ 'use server';
+ const username = formData.get('username');
+ // ...
+}
+
+export default App() {
+
+
+ Request
+
+}
+```
+
+In this example `requestUsername` is a server action passed to a `
`. When a user submits this form, there is a network request to the server function `requestUsername`. When calling a server action in a form, React will supply the form's [FormData](https://developer.mozilla.org/en-US/docs/Web/API/FormData) as the first argument to the server action.
+
+By passing a server action to the form `action`, React can [progressively enhance](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement) the form. This means that forms can be submitted before the JavaScript bundle is loaded.
+
+#### Handling return values in forms {/*handling-return-values*/}
+
+In the username request form, there might be the chance that a username is not available. `requestUsername` should tell us if it fails or not.
+
+To update the UI based on the result of a server action while supporting progressive enhancement, use [`useFormState`](/reference/react-dom/hooks/useFormState).
+
+```js
+// requestUsername.js
+'use server';
+
+export default async function requestUsername(formData) {
+ const username = formData.get('username');
+ if (canRequest(username)) {
+ // ...
+ return 'successful';
+ }
+ return 'failed';
+}
+```
+
+```js {4,8}, [[2, 2, "'use client'"]]
+// UsernameForm.js
+'use client';
+
+import {useFormState} from 'react-dom';
+import requestUsername from './requestUsername';
+
+function UsernameForm() {
+ const [returnValue, action] = useFormState(requestUsername, 'n/a');
+
+ return (
+ <>
+
+
+ Request
+
+
Last submission request returned: {returnValue}
+ >
+ );
+}
+```
+
+Note that like most Hooks, `useFormState` can only be called in [client code](/reference/react/use-client).
+
+### Calling a server action outside of `
` {/*calling-a-server-action-outside-of-form*/}
+
+Server actions are exposed server endpoints and can be called anywhere in client code.
+
+When using a server action outside of a [form](/reference/react-dom/components/form), call the server action in a [transition](/reference/react/useTransition), which allows you to display a loading indicator, show [optimistic state updates](/reference/react/useOptimistic), and handle unexpected errors. Forms will automatically wrap server actions in transitions.
+
+```js {9-12}
+import incrementLike from './actions';
+import { useState, useTransition } from 'react';
+
+function LikeButton() {
+ const [isPending, startTransition] = useTransition();
+ const [likeCount, setLikeCount] = useState(0);
+
+ const onClick = () => {
+ startTransition(async () => {
+ const currentCount = await incrementLike();
+ setLikeCount(currentCount);
+ });
+ };
+
+ return (
+ <>
+
Total Likes: {likeCount}
+ Like;
+ >
+ );
+}
+```
+
+```js
+// actions.js
+'use server';
+
+let likeCount = 0;
+export default async incrementLike() {
+ likeCount++;
+ return likeCount;
+}
+```
+
+To read a server action return value, you'll need to `await` the promise returned.
\ No newline at end of file
diff --git a/src/content/reference/react/useEffect.md b/src/content/reference/react/useEffect.md
index 46f651a8e..e6e4da103 100644
--- a/src/content/reference/react/useEffect.md
+++ b/src/content/reference/react/useEffect.md
@@ -1047,7 +1047,7 @@ Writing `fetch` calls inside Effects is a [popular way to fetch data](https://ww
This list of downsides is not specific to React. It applies to fetching data on mount with any library. Like with routing, data fetching is not trivial to do well, so we recommend the following approaches:
- **If you use a [framework](/learn/start-a-new-react-project#production-grade-react-frameworks), use its built-in data fetching mechanism.** Modern React frameworks have integrated data fetching mechanisms that are efficient and don't suffer from the above pitfalls.
-- **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [React Query](https://react-query.tanstack.com/), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood but also add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).
+- **Otherwise, consider using or building a client-side cache.** Popular open source solutions include [React Query](https://tanstack.com/query/latest/), [useSWR](https://swr.vercel.app/), and [React Router 6.4+.](https://beta.reactrouter.com/en/main/start/overview) You can build your own solution too, in which case you would use Effects under the hood but also add logic for deduplicating requests, caching responses, and avoiding network waterfalls (by preloading data or hoisting data requirements to routes).
You can continue fetching data directly in Effects if neither of these approaches suit you.
diff --git a/src/content/reference/react/useLayoutEffect.md b/src/content/reference/react/useLayoutEffect.md
index 5af3ec5a6..1b65ce3b5 100644
--- a/src/content/reference/react/useLayoutEffect.md
+++ b/src/content/reference/react/useLayoutEffect.md
@@ -732,7 +732,7 @@ However, if you're running into this problem, you have a few different options:
- Replace `useLayoutEffect` with [`useEffect`.](/reference/react/useEffect) This tells React that it's okay to display the initial render result without blocking the paint (because the original HTML will become visible before your Effect runs).
-- Alternatively, [mark your component as client-only.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-server-only-content) This tells React to replace its content up to the closest [``](/reference/react/Suspense) boundary with a loading fallback (for example, a spinner or a glimmer) during server rendering.
+- Alternatively, [mark your component as client-only.](/reference/react/Suspense#providing-a-fallback-for-server-errors-and-client-only-content) This tells React to replace its content up to the closest [``](/reference/react/Suspense) boundary with a loading fallback (for example, a spinner or a glimmer) during server rendering.
- Alternatively, you can render a component with `useLayoutEffect` only after hydration. Keep a boolean `isMounted` state that's initialized to `false`, and set it to `true` inside a `useEffect` call. Your rendering logic can then be like `return isMounted ? : `. On the server and during the hydration, the user will see `FallbackContent` which should not call `useLayoutEffect`. Then React will replace it with `RealContent` which runs on the client only and can include `useLayoutEffect` calls.
diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md
new file mode 100644
index 000000000..d0511b1a9
--- /dev/null
+++ b/src/content/reference/react/useOptimistic.md
@@ -0,0 +1,145 @@
+---
+title: useOptimistic
+canary: true
+---
+
+
+
+The `useOptimistic` Hook is currently only available in React's canary and experimental channels. Learn more about [React's release channels here](/community/versioning-policy#all-release-channels).
+
+
+
+
+
+`useOptimistic` is a React Hook that lets you optimistically update the UI.
+
+```js
+ const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
+```
+
+
+
+
+
+---
+
+## Reference {/*reference*/}
+
+### `useOptimistic(state, updateFn)` {/*use*/}
+
+`useOptimistic` is a React hook that lets you show a different state while an async action is underway. It accepts some state as an argument and returns a copy of that state that can be different during the duration of an async action such as a network request. You provide a function that takes the current state and the input to the action, and returns the optimistic state to be used while the action is pending.
+
+This state is called the "optimistic" state because it is usually used to immediately present the user with the result of performing an action, even though the action actually takes time to complete.
+
+```js
+import { useOptimistic } from 'react';
+
+function AppContainer() {
+ const [optimisticState, addOptimistic] = useOptimistic(
+ state,
+ // updateFn
+ (currentState, optimisticValue) => {
+ // merge and return new state
+ // with optimistic value
+ }
+ );
+}
+```
+
+[See more examples below.](#usage)
+
+#### Parameters {/*parameters*/}
+
+* `state`: the value to be returned initially and whenever no action is pending.
+* `updateFn(currentState, optimisticValue)`: a function that takes the current state and the optimistic value passed to `addOptimistic` and returns the resulting optimistic state. It must be a pure function. `updateFn` takes in two parameters. The `currentState` and the `optimisticValue`. The return value will be the merged value of the `currentState` and `optimisticValue`.
+
+
+#### Returns {/*returns*/}
+
+* `optimisticState`: The resulting optimistic state. It is equal to `state` unless an action is pending, in which case it is equal to the value returned by `updateFn`.
+* `addOptimistic`: `addOptimistic` is the dispatching function to call when you have an optimistic update. It takes one argument, `optimisticValue`, of any type and will call the `updateFn` with `state` and `optimisticValue`.
+
+---
+
+## Usage {/*usage*/}
+
+### Optimistically updating forms {/*optimistically-updating-with-forms*/}
+
+The `useOptimistic` Hook provides a way to optimistically update the user interface before a background operation, like a network request, completes. In the context of forms, this technique helps to make apps feel more responsive. When a user submits a form, instead of waiting for the server's response to reflect the changes, the interface is immediately updated with the expected outcome.
+
+For example, when a user types a message into the form and hits the "Send" button, the `useOptimistic` Hook allows the message to immediately appear in the list with a "Sending..." label, even before the message is actually sent to a server. This "optimistic" approach gives the impression of speed and responsiveness. The form then attempts to truly send the message in the background. Once the server confirms the message has been received, the "Sending..." label is removed.
+
+
+
+
+```js App.js
+import { useOptimistic, useState, useRef } from "react";
+import { deliverMessage } from "./actions.js";
+
+function Thread({ messages, sendMessage }) {
+ const formRef = useRef();
+ async function formAction(formData) {
+ addOptimisticMessage(formData.get("message"));
+ formRef.current.reset();
+ await sendMessage(formData);
+ }
+ const [optimisticMessages, addOptimisticMessage] = useOptimistic(
+ messages,
+ (state, newMessage) => [
+ ...state,
+ {
+ text: newMessage,
+ sending: true
+ }
+ ]
+ );
+
+ return (
+ <>
+ {optimisticMessages.map((message, index) => (
+