From 2831ff60d32a4bb617d17d7ca376fd1c64446542 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Thu, 19 Oct 2023 22:29:48 -0700 Subject: [PATCH 01/17] initial --- .../use_client_module_dependency.dark.png | Bin 0 -> 18311 bytes .../diagrams/use_client_module_dependency.png | Bin 0 -> 18236 bytes .../diagrams/use_client_render_tree.dark.png | Bin 0 -> 13583 bytes .../docs/diagrams/use_client_render_tree.png | Bin 0 -> 13713 bytes src/content/reference/react/use-client.md | 213 +++++++++++++++++- 5 files changed, 207 insertions(+), 6 deletions(-) create mode 100644 public/images/docs/diagrams/use_client_module_dependency.dark.png create mode 100644 public/images/docs/diagrams/use_client_module_dependency.png create mode 100644 public/images/docs/diagrams/use_client_render_tree.dark.png create mode 100644 public/images/docs/diagrams/use_client_render_tree.png 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 0000000000000000000000000000000000000000..c50e7308b08fac14aea09cb7b1e8817ef5ba7a02 GIT binary patch literal 18311 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 FVE3yjM@;8x1#p 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d535246f7f976316cb04096c7ac1fa4afd884e92 GIT binary patch literal 18236 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 b|1CFHb literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..8d3e6a4849ef7298eaea29b3690672d6b75de8c0 GIT binary patch literal 13583 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 OM_xurx=6~v_kRIPAXE1M literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ad3840681cc807f733680710ea47b9563b769c26 GIT binary patch literal 13713 zcmcJ$byQnl*De|;(iSbHO$((sEgD+fOR?fw9D=(P3IqvKrMQ;hR@~i5aA|PY;1qWW zenNlm`@P@!?mc6i`^Oz)uk1DFGv_nsURir)Wv?VaMM;L}KE-_i06--BPErj3zySjQ z*qnFoU^JF)+)J1fj-|MwH~>%@MsR72i;=NDs>!?s6!kq@#|Za6ywmvz01!O9ZCHT# z#3vX7w2Fd;l*|VOfY&d8UpBxm1>l(h@XWjwJ%0h9zX0wj01pgQ4Dd?-i>3oSF~=`} zSH|suvAngv6-6MSxAwOph6JNe!{~+GgKkmG;gJFGNXM9ox`qCw`Wphn;PLB?U)US> zus0vVgdxGguE7`*5w}oL2<8YDb_)`84P=ExbGk)}x`n*)48!Pequd5czdrtRb8~|s z7jX-r3CM?!jlD^z^Q~_8YZ%FfpPG|~hX&FvnBA-atU+CNkvX#(@-c8?rOnvL??Q+sFUR_0QA zXT#gZQ+j87YuXXBYbw8*I3tStP}8KJvpJ(Gd>aS*SGP$$lKN0nb2~>WskKJgjg;-gl|_9+9FQoLUx=dqLC)}!u=a7s;^wfX?*5gX;{L(n(WS7qah0^1yB?|3 z?y)2uNdz7#0&bxKkT3$zl;XZ2a85(t>~zW4VoGP9a#{^Ix1o4!=|d&5cytlRGmX+C z?lmL=$1|M+63GJz=Y@oGMwBS0)~ck|I94K4I{Lr`?TE3lCe)f=S>)n}qrf z@KPFPVu-k?DX9Z?X=vt*5PolHQb|9M&KZTLAUOMX!w@PdoW6d=Z+!bdeCY2FN?fP+s`#F}xfy&w*Vz8&fD9 z-f_HF%8yjPV`gA1?m}E=`(1$4B&{jxjv4f%jK*`?c6D-sjG)KJ&(6!p!tk<*?cfNY zvwGLq!my#q1t+NCO-ygl7asN6^sa|EX5$irT)ZG#118QlF{4s*Gw=eUHlk!Yn$~(5 z`!5#<->DdAS`SP*=izpDgR<{-vC)nxFySaacmrM|0Gwm{!3Ti14RC}D@J<8$ZMVQ% z@ZWX|e1rdOsUW}_fj8D|djkdx0MD^+n;#sI3Od5QZGc-~jo`NVaqS|F3^s;<0PE8g zu7!{51b!74LnP-zzd!)B9prbFsUzGsb>0!fFjU=Xit9Nx%`Du`!+O%&$>QOYb8P)& z_}1?-JBSd<7awC7?;YVKeO1Xbevuso{cπy1S0Fw!_o>-}R6ydeMZ9neX2;rLv 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 O0J2g_l0|QgKL0Nyz#cOI literal 0 HcmV?d00001 diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index f0510415b01..05225346800 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -11,7 +11,7 @@ canary: true -`'use client'` marks source files whose components execute on the client. +`'use client'` marks which components render on the client. @@ -23,9 +23,9 @@ 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 code to be evaluated on the client. -```js +```js {1} 'use client'; import { useState } from 'react'; @@ -34,7 +34,208 @@ export default function RichTextEditor(props) { // ... ``` -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. + + + +#### Client and Server Rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} + +React's full-stack architecture vision is realized through the React Server Components (RSC) specification. + +React Server Components lets you coordinate which components of your [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree) are rendered on the server or on the client. Server rendering is traditionally more performant and allows access to the back-end, while client rendering is necessary for adding interactivity into your components. + +To use React Server Components, you need to use a compatible [React framework](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). These frameworks will render your app on the server by default, unless specified otherwise. + +`'use client'` is how we tell the React framework which component should be rendered on the client. We call components that render on the client, Client Components and server-rendered components, Server Components. + + + +### Marking client code with `'use client'` {/*marking-client-components-with-use-client*/} + +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'` marks which modules in the [module dependency tree](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree) are downloaded and evaluated on the client. When a server-rendered module imports a `'use client'` module, the `use client` module and all its transitive dependencies will be run on the client. + +To better illustrate this, consider the following React Server Component app and its render and module dependency tree. + + + +```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 + ?

{text}

+ :

{text}

+} +``` + +```js InspirationGenerator.js +'use client'; + +import * as React from 'react'; +import quotes from './quotes'; +import FancyText from './FancyText'; + +export default function InspirationGenerator({children}) { + const [index, setIndex] = React.useState(0); + const quote = quotes[index]; + const next = () => setIndex((index + 1) % quotes.length); + + return ( + <> +

Your inspirational quote is:

+ + + {children} + + ); +} +``` + +```js Copyright.js +export default function Copyright({year}) { + return

©️ {year}

; +} +``` + +```js quotes.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; +} +``` + +
+ + +`'use client'` segments the module dependency tree of the React Server Components app to mark `InspirationGenerator.js` and any of its dependencies as client-rendered. + + +In the module dependency tree of the example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client code. Only client-marked code will be bundled, downloaded and evaluated by the client. + +Irregardless if a module exports a component, like `inspirations.js`, if a module is transitive dependency of a `'use client'` module, then it will only be evaluated on the client. + +In rendering, 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**. + +``` +// This is a definition of a component +function MyComponent() { + return

My Component

+} +``` + +2. A "component" can also refer to a **component usage** of a definition. +``` +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. Where a component is imported and used determines if it is a Server or Client Component, with one notable exception. + +* If the component is imported and used in a Client Component, then the component usage is a Client Component. +* If the component is imported and used in a Server Component, then the component usage is a Server Component. + +The exception is if a component is defined in a module with a `'use client'` directive. In that case, regardless of where the component is imported and used, every component usage will be a Client Component. + +Looking back to the question of `FancyText`, it's now clear that a render tree is a tree of component usages. + +A render tree is a tree of component usages. + +The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and used under `InspirationGenerator`, that usage of `FancyText` is a Client Component. + +This also means that the component definition for `FancyText` will both be evaluated on the server and also be downlaoded by the client to render its Client Component usage. + +
+ + + +#### Why is `Copyright` a Server Component? {/*why-is-copyright-a-server-component*/} + +`Copyright` is a Server Component because it is imported and used by the Server Component `App`. + +This may be unintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. + +This is because `InspirationGenerator` accepts [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) but the actual import and usage of the component occurs within `App`, a Server Component, because it is a root component. + +In a module dependency tree, a node that represents a module with a `'use client'` will mark every descendent node to be client-run -- however the same is not true for a Client Component in a render true. + + + + +### Passing props from Server to Client Components {/*passing-props-from-server-to-client-components*/} + +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 need to be serializable. + +Serializable props include: +* [JavaScript primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) +* Subclasses of [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)s +* + + #### Caveats {/*caveats*/} @@ -51,9 +252,9 @@ When a file marked `'use client'` is imported from a server component, [compatib ## Usage {/*usage*/} -This section is a work in progress. +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 + From 44a256b6ccd5bd384754be7c03588708d5f9dc71 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Thu, 19 Oct 2023 22:40:26 -0700 Subject: [PATCH 02/17] flesh out alt description --- src/content/reference/react/use-client.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 05225346800..a71c41157f1 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -141,7 +141,7 @@ export default [ - + `'use client'` segments the module dependency tree of the React Server Components app to mark `InspirationGenerator.js` and any of its dependencies as client-rendered. @@ -153,7 +153,7 @@ In rendering, the framework will server-render the root component and continue t 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. @@ -201,7 +201,7 @@ The exception is if a component is defined in a module with a `'use client'` dir Looking back to the question of `FancyText`, it's now clear that a render tree is a tree of component usages. -A render tree is a tree of component usages. +A render tree is a tree of component usages. The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and used under `InspirationGenerator`, that usage of `FancyText` is a Client Component. @@ -232,7 +232,7 @@ Prop values passed from a Server Component to Client Component need to be serial Serializable props include: * [JavaScript primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) -* Subclasses of [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)s +* Subclasses of [TypedArrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) * From 3db97a32bc2b2a125dfdd8a96a80932a6a6ad225 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 20 Oct 2023 12:51:09 -0700 Subject: [PATCH 03/17] flesh out the serializable props and caveats --- src/content/reference/react/use-client.md | 48 ++++++++++++++++------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index a71c41157f1..6df35f0d9be 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -228,26 +228,44 @@ In a module dependency tree, a node that represents a module with a `'use client 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 need to be serializable. - -Serializable props include: -* [JavaScript primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) -* Subclasses of [TypedArrays](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) -* +Prop values passed from a Server Component to Client Component must be serializable. +[TODO]: <> (Link to use server docs) +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 + * [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) +* 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 +* Client or Server Components +* [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'` +* [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) +* Objects that are not an instance of [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), or [null-prototype objects](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')` #### 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 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. + ## Usage {/*usage*/} From d426f6a69e72a86a2674d3988a3e0a307ae52cd7 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Mon, 23 Oct 2023 15:30:27 -0700 Subject: [PATCH 04/17] finish up usages --- src/content/reference/react/use-client.md | 148 ++++++++++++++++++---- 1 file changed, 123 insertions(+), 25 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 6df35f0d9be..7cfafdaf684 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -52,11 +52,11 @@ To use React Server Components, you need to use a compatible [React framework](/ ### Marking client code with `'use client'` {/*marking-client-components-with-use-client*/} -In a React app, components are often split into separate files, or [modules](/learn/importing-and-exporting-components#exporting-and-importing-a-component). +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'` marks which modules in the [module dependency tree](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree) are downloaded and evaluated on the client. When a server-rendered module imports a `'use client'` module, the `use client` module and all its transitive dependencies will be run on the client. +For apps that use React Server Components, the app is server-rendered by default. `'use client'` creates a client-module subtree in the [module dependency tree](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree). When a server-rendered module imports a `'use client'` module, the `use client` module and all its transitive dependencies will be run on the client. -To better illustrate this, consider the following React Server Component app and its render and module dependency tree. +To better illustrate this, consider the following React Server Component app module dependency and render tree. @@ -87,7 +87,7 @@ export default function FancyText({title, text}) { ``` ```js InspirationGenerator.js -'use client'; +'use client'; import * as React from 'react'; import quotes from './quotes'; @@ -145,13 +145,13 @@ export default [ `'use client'` segments the module dependency tree of the React Server Components app to mark `InspirationGenerator.js` and any of its dependencies as client-rendered. -In the module dependency tree of the example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client code. Only client-marked code will be bundled, downloaded and evaluated by the client. +In the module dependency tree of the example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client modules. It creates a subtree of client modules with `InspirationGenerator.js` as the root. -Irregardless if a module exports a component, like `inspirations.js`, if a module is transitive dependency of a `'use client'` module, then it will only be evaluated on the client. +Irregardless if a module exports a component, like `inspirations.js`, if a module is part of that client subtree, then it will be evaluated on the client. -In rendering, 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. +In rendering, 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 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. @@ -173,15 +173,15 @@ First, let's clarify that the term "component" is not very precise. Here are jus 1. A "component" can refer to a **component definition**. -``` +```js // This is a definition of a component function MyComponent() { return

My Component

} ``` -2. A "component" can also refer to a **component usage** of a definition. -``` +2. A "component" can also refer to a **component usage** of a definition. +```js import MyComponent from './MyComponent'; function App() { @@ -195,15 +195,15 @@ Often, the imprecision is not important when explaining concepts, but in this ca When we talk about Server or Client Components, we are referring to component usages. Where a component is imported and used determines if it is a Server or Client Component, with one notable exception. * If the component is imported and used in a Client Component, then the component usage is a Client Component. -* If the component is imported and used in a Server Component, then the component usage is a Server Component. +* If the component is imported and used in a Server Component, then the component usage is a Server Component. -The exception is if a component is defined in a module with a `'use client'` directive. In that case, regardless of where the component is imported and used, every component usage will be a Client Component. +The exception is if a component is defined in a module with a `'use client'` directive. In that case, regardless of where the component is imported and used, every component usage will be a Client Component. -Looking back to the question of `FancyText`, it's now clear that a render tree is a tree of component usages. +Looking back to the question of `FancyText`, it's now clear that a render tree is a tree of component usages. A render tree is a tree of component usages. -The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and used under `InspirationGenerator`, that usage of `FancyText` is a Client Component. +The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and used under `InspirationGenerator`, that usage of `FancyText` is a Client Component. This also means that the component definition for `FancyText` will both be evaluated on the server and also be downlaoded by the client to render its Client Component usage. @@ -213,9 +213,9 @@ This also means that the component definition for `FancyText` will both be evalu #### Why is `Copyright` a Server Component? {/*why-is-copyright-a-server-component*/} -`Copyright` is a Server Component because it is imported and used by the Server Component `App`. +`Copyright` is a Server Component because it is imported and used by the Server Component `App`. -This may be unintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. +This may be unintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. This is because `InspirationGenerator` accepts [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) but the actual import and usage of the component occurs within `App`, a Server Component, because it is a root component. @@ -223,6 +223,21 @@ In a module dependency tree, a node that represents a module with a `'use client +### Server Component advantages and limitations {/*server-component-advantages-and-limitations*/} + +With `'use client'`, you can determine what components will be Server or Client Components. To understand when to use Client Components, here is an overview of the advantages and limitations to Server Components. + +For simplicity, we talk about Server Components, but the same principles apply to all code in your app that is server run. + +#### Advantages {/*advantages*/} +* Server Components 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 {/*limitations*/} +* Server Components cannot support interaction as event handlers must be registered and triggered by a client. + * The browser, as an example client, is responsible for delegating UI clicks to the appropriate `onClick` handler. +* Server Components cannot use most Hooks. + * When Server Components are rendered, they are conceptually resolved into instructions for the client to interpret and turn into UI primitives. This means that Server Components do not persist in memory after render and do not support re-rendering or state. ### Passing props from Server to Client Components {/*passing-props-from-server-to-client-components*/} @@ -259,20 +274,103 @@ Notably, these are not supported: #### Caveats {/*caveats*/} -* `'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. +* `'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 it is a transitive dependency of a module that contains a `'use client'` directive. Otherwise, it is a Server Component. + * A component usage is considered a Client Component if it is defined in module with `'use client'` directive or 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. ## 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}

+ + + ); +} +``` + +
+ +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 {getCounterValueFromFile} from 'fs-utils'; +import Counter from './Counter'; + +export default async function CounterContainer() { + const initialValue = await getCounterValueFromFile(); + return +} +``` + +For example, the parent component of the Client Component `CounterContainer` does not require `'use client'` as it is not interactive and does not use state. To be more specific, `CounterContainer` must be a Server Component as it reads from the local file system on the server. Notably, Server Components support asynchronous rendering, which is not supported for Client Components. + +There are also components that don't use any server or client-only features and can be agnostic to where they render. `FancyText` is an example of such a component. + +```js +export default function FancyText({title, text}) { + return title + ?

{text}

+ :

{text}

+} +``` + +In this case, it is discouraged to use the `'use client'` directive as it pre-maturely forces all component usages of `FancyText` to be rendered on the client, which comes at a performance cost. 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. + +### Using client APIs {/*using-client-apis*/} + +Your React app may use client-specific APIs which are dependent on your targeted client. For the browser, some example client APIs include web storage, audio and video manipulation, device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API). + +In this example, the component references the [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element and [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM) through the `ref`. Both of which are only accessible on the browser so this component 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.beginPath(); + context.arc(100, 75, 50, 0, 2 * Math.PI); + context.stroke(); + }); + return +} +``` + +### Using React libraries {/*using-react-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. In these cases, you'll need to ensure you're using these libraries in Client Components. Depending on the nature of these libraries, this may mean adding a `'use client'` near the top of your module dependency tree – marking the majority of your React app as client-rendered. + +Libraries that use any of the following React APIs must be marked as client-run: +* [createContext](/reference/react/createContext) +* [`react`](/reference/react) and [`react-dom`](/reference/react-dom/hooks) Hooks +* [forwardRef](/reference/react/forwardRef) +* [memo](/reference/react/memo) +* [startTransition](/reference/react/startTransition) +* If they use client APIs, ex. DOM insertion or native platform views -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 -
+[TODO]: <> (Troubleshooting - need use-cases) \ No newline at end of file From 77ef7258c8d70da4a946f918b3581ddab8d3f7b6 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Mon, 23 Oct 2023 21:56:05 -0700 Subject: [PATCH 05/17] try and clarify boundary usage --- src/content/reference/react/use-client.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 7cfafdaf684..e4785b10086 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -11,7 +11,7 @@ canary: true -`'use client'` marks which components render on the client. +`'use client'` lets you mark what code runs on the client. @@ -23,19 +23,28 @@ canary: true ### `'use client'` {/*use-client*/} -Add `'use client'` at the top of a file to mark the code to be evaluated on the client. +Add `'use client'` at the top of a file to mark the module and its transitive dependencies as client code. ```js {1} 'use client'; import { useState } from 'react'; +import { formatDate } from './formatters'; +import Link from './link'; export default function RichTextEditor(props) { + formatDate(); // ... + return + + // ... +} ``` 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 a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client irregardless if their modules contain a `'use client'` directive. + #### Client and Server Rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} @@ -46,17 +55,15 @@ React Server Components lets you coordinate which components of your [render tre To use React Server Components, you need to use a compatible [React framework](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). These frameworks will render your app on the server by default, unless specified otherwise. -`'use client'` is how we tell the React framework which component should be rendered on the client. We call components that render on the client, Client Components and server-rendered components, Server Components. - ### Marking client code with `'use client'` {/*marking-client-components-with-use-client*/} 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'` creates a client-module subtree in the [module dependency tree](/learn/understanding-your-ui-as-a-tree#the-module-dependency-tree). When a server-rendered module imports a `'use client'` module, the `use client` module and all its transitive dependencies will be run on the client. +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 client-module subtree. -To better illustrate this, consider the following React Server Component app module dependency and render tree. +To better illustrate this, consider the following React Server Component app and its module dependency and render tree. @@ -215,7 +222,7 @@ This also means that the component definition for `FancyText` will both be evalu `Copyright` is a Server Component because it is imported and used by the Server Component `App`. -This may be unintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. +This may be counterintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. This is because `InspirationGenerator` accepts [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) but the actual import and usage of the component occurs within `App`, a Server Component, because it is a root component. From 054785456503c8669d23bc5642073ac2361031f6 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 24 Oct 2023 00:42:37 -0700 Subject: [PATCH 06/17] update usage to callsite --- src/content/reference/react/use-client.md | 49 ++++++++++++----------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index e4785b10086..b28c5ec26ce 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -43,13 +43,13 @@ export default function RichTextEditor(props) { 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 a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client irregardless if their modules contain a `'use client'` directive. +As a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client regardless if their modules contain a `'use client'` directive. #### Client and Server Rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} -React's full-stack architecture vision is realized through the React Server Components (RSC) specification. +React's full-stack architecture vision is realized through the [React Server Components (RSC) specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). React Server Components lets you coordinate which components of your [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree) are rendered on the server or on the client. Server rendering is traditionally more performant and allows access to the back-end, while client rendering is necessary for adding interactivity into your components. @@ -97,13 +97,13 @@ export default function FancyText({title, text}) { 'use client'; import * as React from 'react'; -import quotes from './quotes'; +import inspirations from './inspirations'; import FancyText from './FancyText'; export default function InspirationGenerator({children}) { const [index, setIndex] = React.useState(0); - const quote = quotes[index]; - const next = () => setIndex((index + 1) % quotes.length); + const quote = inspirations[index]; + const next = () => setIndex((index + 1) % inspirations.length); return ( <> @@ -122,12 +122,12 @@ export default function Copyright({year}) { } ``` -```js quotes.js +```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 @@ -154,8 +154,6 @@ export default [ In the module dependency tree of the example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client modules. It creates a subtree of client modules with `InspirationGenerator.js` as the root. -Irregardless if a module exports a component, like `inspirations.js`, if a module is part of that client subtree, then it will be evaluated on the client. - In rendering, 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. @@ -178,7 +176,7 @@ By the above definitions, the component `FancyText` is both a Server and Client 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**. +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 @@ -187,7 +185,7 @@ function MyComponent() { } ``` -2. A "component" can also refer to a **component usage** of a definition. +2. A "component" can also refer to a **component callsite** of its definition. ```js import MyComponent from './MyComponent'; @@ -199,20 +197,19 @@ function App() { 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. Where a component is imported and used determines if it is a Server or Client Component, with one notable exception. +When we talk about Server or Client Components, we are referring to component callsites. -* If the component is imported and used in a Client Component, then the component usage is a Client Component. -* If the component is imported and used in a Server Component, then the component usage is a Server Component. +* 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 callsite is a Client Component. +* If the component is imported and called in a Server Component, then the component callsite is a Server Component. -The exception is if a component is defined in a module with a `'use client'` directive. In that case, regardless of where the component is imported and used, every component usage will be a Client Component. -Looking back to the question of `FancyText`, it's now clear that a render tree is a tree of component usages. +A render tree illustrates component callsites. -A render tree is a tree of 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 callsites. -The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and used under `InspirationGenerator`, that usage of `FancyText` is a Client Component. +The callsite of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and called under `InspirationGenerator`, that callsite of `FancyText` is a Client Component as `InspirationGenerator` is a Client Component since it contains a `'use client'` directive. -This also means that the component definition for `FancyText` will both be evaluated on the server and also be downlaoded by the client to render its Client Component usage. +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. @@ -220,13 +217,19 @@ This also means that the component definition for `FancyText` will both be evalu #### Why is `Copyright` a Server Component? {/*why-is-copyright-a-server-component*/} -`Copyright` is a Server Component because it is imported and used by the Server Component `App`. +As a child of `InspirationGenerator`, a Client Component, why is `Copyright` a Server Component? + +To clarify, `'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. + -This may be counterintuitive as `Copyright` is a child component of `InspirationGenerator`, which is a Client Component. +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 callsite is rendered on the server. `App` is rendered on the server as it is the root component. -This is because `InspirationGenerator` accepts [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) but the actual import and usage of the component occurs within `App`, a Server Component, because it is a root component. +Client Components can render Server Components because you can pass JSX as props. In this case, `InspirationGenerator` takes [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) and receives `Copyright` as a `children` prop. However, the `InspirationGenerator` module never directly imports the `Copyright` module nor calls the component, all of that is done by `App`. -In a module dependency tree, a node that represents a module with a `'use client'` will mark every descendent node to be client-run -- however the same is not true for a Client Component in a render true. +The takeaway is that a parent-child render relationship between components does not guarantee the same render environment. From a71b522551e9e07cea37d1afba197d79c5c97e66 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Tue, 24 Oct 2023 00:44:36 -0700 Subject: [PATCH 07/17] during render --- src/content/reference/react/use-client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index b28c5ec26ce..4f295ec86fc 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -154,7 +154,7 @@ export default [ In the module dependency tree of the example app, the `'use client'` directive in `InspirationGenerator.js` marks that module and all of its transitive dependencies as client modules. It creates a subtree of client modules with `InspirationGenerator.js` as the root. -In rendering, 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. +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. From e1415a199f999c8474bb014b936a85f319029016 Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 25 Oct 2023 10:54:23 -0700 Subject: [PATCH 08/17] Update src/content/reference/react/use-client.md --- src/content/reference/react/use-client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 4f295ec86fc..bcea264276d 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -207,7 +207,7 @@ When we talk about Server or Client Components, we are referring to component ca Back to the question of `FancyText`, we see that the component definition does _not_ have a `'use client'` directive and it has two callsites. -The callsite of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and called under `InspirationGenerator`, that callsite of `FancyText` is a Client Component as `InspirationGenerator` is a Client Component since it contains a `'use client'` directive. +The callsite of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and called under `InspirationGenerator`, that callsite 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. From 7793af6db7a2faa6cc22c394603b875a1faac8bd Mon Sep 17 00:00:00 2001 From: Luna Date: Wed, 25 Oct 2023 10:55:30 -0700 Subject: [PATCH 09/17] Apply suggestions from code review Co-authored-by: Soichiro Miki --- src/content/reference/react/use-client.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index bcea264276d..3b9d5ec4743 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -47,7 +47,7 @@ As a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evalu -#### Client and Server Rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} +#### Client and server rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} React's full-stack architecture vision is realized through the [React Server Components (RSC) specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). @@ -190,7 +190,7 @@ function MyComponent() { import MyComponent from './MyComponent'; function App() { - // This is a usage of a component + // This is a callsite of a component return ; } ``` @@ -227,7 +227,7 @@ To clarify, `'use client'` defines the boundary between server and client code o 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 callsite 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` takes [JSX as children props](/learn/passing-props-to-a-component#passing-jsx-as-children) and receives `Copyright` as a `children` prop. However, the `InspirationGenerator` module never directly imports the `Copyright` module nor calls the component, all of that is done by `App`. +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`. The takeaway is that a parent-child render relationship between components does not guarantee the same render environment. @@ -279,7 +279,7 @@ Serializable props include: 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'` * [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) -* Objects that are not an instance of [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), or [null-prototype objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects) +* Objects that are not an instance of [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), or are [null-prototype objects](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')` #### Caveats {/*caveats*/} From 10605d3634b63efd0c49a058bcf550ead54db533 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 14:12:40 -0700 Subject: [PATCH 10/17] update serializable type wording like use-server --- src/content/reference/react/use-client.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 3b9d5ec4743..41024f1a09e 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -266,12 +266,14 @@ Serializable props include: * [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 +* 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) +* [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 * Client or Server Components * [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) @@ -279,7 +281,7 @@ Serializable props include: 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'` * [Classes](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Classes_in_JavaScript) -* Objects that are not an instance of [Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object), or are [null-prototype objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#null-prototype_objects) +* Objects that are instances of any class (other than built-ins mentioned) or objects with [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')` #### Caveats {/*caveats*/} From 85db687d544c156eea9545f4ecf586de53f90823 Mon Sep 17 00:00:00 2001 From: Luna Date: Fri, 27 Oct 2023 14:28:35 -0700 Subject: [PATCH 11/17] Update src/content/reference/react/use-client.md Co-authored-by: David McCabe --- src/content/reference/react/use-client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 3b9d5ec4743..c406378d2d1 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -349,7 +349,7 @@ In this case, it is discouraged to use the `'use client'` directive as it pre-ma Your React app may use client-specific APIs which are dependent on your targeted client. For the browser, some example client APIs include web storage, audio and video manipulation, device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API). -In this example, the component references the [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element and [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM) through the `ref`. Both of which are only accessible on the browser so this component must be marked as a Client Component. +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'; From ef919816beb1ce22143b67724f02d8bff1e385ae Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 14:30:39 -0700 Subject: [PATCH 12/17] updates from review --- src/content/reference/react/use-client.md | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 41024f1a09e..fcafa3d0c9e 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -43,7 +43,7 @@ export default function RichTextEditor(props) { 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 a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client regardless if their modules contain a `'use client'` directive. +As a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client regardless of whether their modules contain a `'use client'` directive. Note that the same module may be evaluated on the server when imported from server code and on the client when imported from client code. @@ -51,7 +51,7 @@ As a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evalu React's full-stack architecture vision is realized through the [React Server Components (RSC) specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). -React Server Components lets you coordinate which components of your [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree) are rendered on the server or on the client. Server rendering is traditionally more performant and allows access to the back-end, while client rendering is necessary for adding interactivity into your components. +React Server Components lets you coordinate which components of your [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree) are rendered on the server or on the client. Server rendering is generally more performant and allows access to the back-end, while client rendering is necessary for adding interactivity into your components. To use React Server Components, you need to use a compatible [React framework](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). These frameworks will render your app on the server by default, unless specified otherwise. @@ -185,29 +185,29 @@ function MyComponent() { } ``` -2. A "component" can also refer to a **component callsite** of its definition. +2. A "component" can also refer to a **component usage** of its definition. ```js import MyComponent from './MyComponent'; function App() { - // This is a callsite of a component + // 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 callsites. +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 callsite is a Client Component. -* If the component is imported and called in a Server Component, then the component callsite is a Server Component. +* 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 callsites. +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 callsites. +Back to the question of `FancyText`, we see that the component definition does _not_ have a `'use client'` directive and it has two . -The callsite of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. When `FancyText` is imported and called under `InspirationGenerator`, that callsite of `FancyText` is a Client Component as `InspirationGenerator` contains a `'use client'` directive. +The usage of `FancyText` as a child of `App`, marks that usage as a Server Component as root components are always Server Components. 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. @@ -225,7 +225,7 @@ To clarify, `'use client'` defines the boundary between server and client code o `'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 callsite is rendered on the server. `App` is rendered on the server as it is the root component. +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`. @@ -289,7 +289,7 @@ Notably, these are not supported: * `'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 it is a transitive dependency of a module that contains a `'use client'` directive. Otherwise, it is a Server Component. + * 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. @@ -333,7 +333,7 @@ export default async function CounterContainer() { } ``` -For example, the parent component of the Client Component `CounterContainer` does not require `'use client'` as it is not interactive and does not use state. To be more specific, `CounterContainer` must be a Server Component as it reads from the local file system on the server. Notably, Server Components support asynchronous rendering, which is not supported for Client Components. +For example, the parent component of the Client 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. This is possible because Server Components, unlike Client Components, can be async functions. There are also components that don't use any server or client-only features and can be agnostic to where they render. `FancyText` is an example of such a component. @@ -345,11 +345,11 @@ export default function FancyText({title, text}) { } ``` -In this case, it is discouraged to use the `'use client'` directive as it pre-maturely forces all component usages of `FancyText` to be rendered on the client, which comes at a performance cost. 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. +In this case, it is discouraged to use the `'use client'` directive as it prematurely forces all component usages of `FancyText` to be rendered on the client, which comes at a performance cost. 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. ### Using client APIs {/*using-client-apis*/} -Your React app may use client-specific APIs which are dependent on your targeted client. For the browser, some example client APIs include web storage, audio and video manipulation, device hardware, among [others](https://developer.mozilla.org/en-US/docs/Web/API). +Your React app may use client-specific APIs which are dependent on your targeted client. For the browser, some example client APIs include 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 references the [`canvas`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) element and [DOM](https://developer.mozilla.org/en-US/docs/Glossary/DOM) through the `ref`. Both of which are only accessible on the browser so this component must be marked as a Client Component. From a6db8e0b7c6666c8f2f4776f7c6b6bdf5acd21d7 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 14:39:16 -0700 Subject: [PATCH 13/17] updates --- src/content/reference/react/use-client.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index e8dffc5bac2..9964e078505 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -205,9 +205,9 @@ When we talk about Server or Client Components, we are referring to component us 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 . +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 as root components are always Server Components. When `FancyText` is imported and called under `InspirationGenerator`, that usage of `FancyText` is a Client Component as `InspirationGenerator` contains a `'use client'` directive. +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. @@ -240,7 +240,7 @@ With `'use client'`, you can determine what components will be Server or Client For simplicity, we talk about Server Components, but the same principles apply to all code in your app that is server run. #### Advantages {/*advantages*/} -* Server Components reduce the amount of code sent and run by the client. Only client modules are bundled and evaluated by the client. +* 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 {/*limitations*/} @@ -279,7 +279,7 @@ Serializable props include: * [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'` +* [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 built-ins mentioned) or objects with [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')` From e3682512c3030f429cee65e8cb06a28c9d79dc5d Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 14:54:16 -0700 Subject: [PATCH 14/17] better title for pro/con for server components --- src/content/reference/react/directives.md | 2 +- src/content/reference/react/use-client.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/directives.md b/src/content/reference/react/directives.md index b323dab1dc7..4854310b3c4 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/use-client.md b/src/content/reference/react/use-client.md index 9964e078505..b7d61dc9998 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -233,9 +233,9 @@ The takeaway is that a parent-child render relationship between components does -### Server Component advantages and limitations {/*server-component-advantages-and-limitations*/} +### When to use `'use client'` {/*when-to-use-use-client*/} -With `'use client'`, you can determine what components will be Server or Client Components. To understand when to use Client Components, here is an overview of the advantages and limitations to Server Components. +With `'use client'`, you can determine what component usages will be 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. From 59342746289c1740de26ae2de65a795ea1b51982 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 14:57:03 -0700 Subject: [PATCH 15/17] add use, useId exceptions --- src/content/reference/react/use-client.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index b7d61dc9998..ed3b9f3f85b 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -379,7 +379,7 @@ These libraries may rely on component Hooks or client APIs. In these cases, you' Libraries that use any of the following React APIs must be marked as client-run: * [createContext](/reference/react/createContext) -* [`react`](/reference/react) and [`react-dom`](/reference/react-dom/hooks) Hooks +* [`react`](/reference/react) 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) From 0a1f022fe7582120b01d58718ec7c1507c303803 Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Fri, 27 Oct 2023 15:00:32 -0700 Subject: [PATCH 16/17] fix imports --- src/content/reference/react/use-client.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index ed3b9f3f85b..92fea2abac8 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -96,12 +96,12 @@ export default function FancyText({title, text}) { ```js InspirationGenerator.js 'use client'; -import * as React from 'react'; +import { useState } from 'react'; import inspirations from './inspirations'; import FancyText from './FancyText'; export default function InspirationGenerator({children}) { - const [index, setIndex] = React.useState(0); + const [index, setIndex] = useState(0); const quote = inspirations[index]; const next = () => setIndex((index + 1) % inspirations.length); @@ -303,7 +303,7 @@ Notably, these are not supported: ```js App.js 'use client'; -import {useState} from 'react'; +import { useState } from 'react'; export default function Counter({initialValue = 0}) { const [countValue, setCountValue] = useState(initialValue); From 3fc9136e63d1cf8d80aaf1ddb72e2eb8a5b838af Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Mon, 30 Oct 2023 14:58:04 -0700 Subject: [PATCH 17/17] Remove background deep dive, rename title and use new hooks link --- src/content/reference/react/use-client.md | 32 +++++++---------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/src/content/reference/react/use-client.md b/src/content/reference/react/use-client.md index 92fea2abac8..7c8df868c7d 100644 --- a/src/content/reference/react/use-client.md +++ b/src/content/reference/react/use-client.md @@ -45,19 +45,16 @@ When a file marked with `'use client'` is imported from a Server Component, [com As a dependency of `RichTextEditor`, `formatDate` and `Link` will also be evaluated on the client regardless of whether their modules contain a `'use client'` directive. Note that the same module may be evaluated on the server when imported from server code and on the client when imported from client code. - - -#### Client and server rendering with React Server Components {/*client-and-server-rendering-with-react-server-components*/} - -React's full-stack architecture vision is realized through the [React Server Components (RSC) specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). - -React Server Components lets you coordinate which components of your [render tree](/learn/understanding-your-ui-as-a-tree#the-render-tree) are rendered on the server or on the client. Server rendering is generally more performant and allows access to the back-end, while client rendering is necessary for adding interactivity into your components. - -To use React Server Components, you need to use a compatible [React framework](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). These frameworks will render your app on the server by default, unless specified otherwise. +#### Caveats {/*caveats*/} - +* `'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. -### Marking client code with `'use client'` {/*marking-client-components-with-use-client*/} +### 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). @@ -255,8 +252,6 @@ As in any React app, parent components pass data to child components. As they ar Prop values passed from a Server Component to Client Component must be serializable. -[TODO]: <> (Link to use server docs) - Serializable props include: * Primitives * [string](https://developer.mozilla.org/en-US/docs/Glossary/String) @@ -284,15 +279,6 @@ Notably, these are not supported: * Objects that are instances of any class (other than built-ins mentioned) or objects with [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')` -#### Caveats {/*caveats*/} - -* `'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. - ## Usage {/*usage*/} @@ -379,7 +365,7 @@ These libraries may rely on component Hooks or client APIs. In these cases, you' Libraries that use any of the following React APIs must be marked as client-run: * [createContext](/reference/react/createContext) -* [`react`](/reference/react) and [`react-dom`](/reference/react-dom/hooks) Hooks, excluding [`use`](/reference/react/use) and [`useId`](/reference/react/useId) +* [`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)