From d3a5f8a8033d1fe13b2f1482875bc30bc9521244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xuan=20Huang=20=28=E9=BB=84=E7=8E=84=29?= Date: Tue, 14 Nov 2023 22:49:26 +0800 Subject: [PATCH 01/17] Capitalize word "Fragment" (#6425) Summary of changes: See Co-authored-by: xuan.huang --- src/content/blog/2023/03/16/introducing-react-dev.md | 3 +-- src/content/learn/conditional-rendering.md | 2 +- src/content/learn/rendering-lists.md | 6 +++--- src/content/learn/tutorial-tic-tac-toe.md | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/content/blog/2023/03/16/introducing-react-dev.md b/src/content/blog/2023/03/16/introducing-react-dev.md index d27673d90..d2e11fded 100644 --- a/src/content/blog/2023/03/16/introducing-react-dev.md +++ b/src/content/blog/2023/03/16/introducing-react-dev.md @@ -428,7 +428,7 @@ export default function PackingList() { Note that you must write `importance > 0 && ...` rather than `importance && ...` so that if the `importance` is `0`, `0` isn't rendered as the result! -In this solution, two separate conditions are used to insert a space between then name and the importance label. Alternatively, you could use a fragment with a leading space: `importance > 0 && <> ...` or add a space immediately inside the ``: `importance > 0 && ...`. +In this solution, two separate conditions are used to insert a space between then name and the importance label. Alternatively, you could use a Fragment with a leading space: `importance > 0 && <> ...` or add a space immediately inside the ``: `importance > 0 && ...`. @@ -643,4 +643,3 @@ On the development front, thanks to [Jared Palmer](https://twitter.com/jaredpalm Huge thanks to the folks who volunteered their time to participate in the alpha and beta testing program. Your enthusiasm and invaluable feedback helped us shape these docs. A special shout out to our beta tester, [Debbie O'Brien](https://twitter.com/debs_obrien), who gave a talk about her experience using the React docs at React Conf 2021. Finally, thanks to the React community for being the inspiration behind this effort. You are the reason we do this, and we hope that the new docs will help you use React to build any user interface that you want. - diff --git a/src/content/learn/conditional-rendering.md b/src/content/learn/conditional-rendering.md index cfd52320a..895d610d3 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -626,7 +626,7 @@ export default function PackingList() { Note that you must write `importance > 0 && ...` rather than `importance && ...` so that if the `importance` is `0`, `0` isn't rendered as the result! -In this solution, two separate conditions are used to insert a space between the name and the importance label. Alternatively, you could use a fragment with a leading space: `importance > 0 && <> ...` or add a space immediately inside the ``: `importance > 0 && ...`. +In this solution, two separate conditions are used to insert a space between the name and the importance label. Alternatively, you could use a Fragment with a leading space: `importance > 0 && <> ...` or add a space immediately inside the ``: `importance > 0 && ...`. diff --git a/src/content/learn/rendering-lists.md b/src/content/learn/rendering-lists.md index 13ac932fb..5b07afd93 100644 --- a/src/content/learn/rendering-lists.md +++ b/src/content/learn/rendering-lists.md @@ -1145,7 +1145,7 @@ hr { -You'll either need to convert `map` to a manual loop, or use a fragment. +You'll either need to convert `map` to a manual loop, or use a Fragment. @@ -1208,7 +1208,7 @@ hr { Using the original line index as a `key` doesn't work anymore because each separator and paragraph are now in the same array. However, you can give each of them a distinct key using a suffix, e.g. `key={i + '-text'}`. -Alternatively, you could render a collection of fragments which contain `
` and `

...

`. However, the `<>...` shorthand syntax doesn't support passing keys, so you'd have to write `` explicitly: +Alternatively, you could render a collection of Fragments which contain `
` and `

...

`. However, the `<>...` shorthand syntax doesn't support passing keys, so you'd have to write `` explicitly: @@ -1254,7 +1254,7 @@ hr { -Remember, fragments (often written as `<> `) let you group JSX nodes without adding extra `
`s! +Remember, Fragments (often written as `<> `) let you group JSX nodes without adding extra `
`s! diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index eca388a88..b40a90572 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -362,11 +362,11 @@ You'll get this error: -/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment `<>...`? +/src/App.js: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX Fragment `<>...`? -React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *fragments* (`<>` and ``) to wrap multiple adjacent JSX elements like this: +React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *Fragments* (`<>` and ``) to wrap multiple adjacent JSX elements like this: ```js {3-6} export default function Square() { From 4f9e9a56611c7a56b9506cf0a7ca84ab409824bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xuan=20Huang=20=28=E9=BB=84=E7=8E=84=29?= Date: Tue, 14 Nov 2023 22:49:55 +0800 Subject: [PATCH 02/17] Capitalize word "Canary" (#6427) Summary of changes: See Co-authored-by: xuan.huang --- src/content/community/versioning-policy.md | 2 +- src/content/reference/react-dom/components/input.md | 2 +- src/content/reference/react-dom/hooks/useFormState.md | 2 +- src/content/reference/react-dom/hooks/useFormStatus.md | 2 +- src/content/reference/react/use.md | 2 +- src/content/reference/react/useOptimistic.md | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/content/community/versioning-policy.md b/src/content/community/versioning-policy.md index 68d5b8eb1..eb38f8c29 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -46,7 +46,7 @@ In general, we *don't* bump the major version number for changes to: * **Development warnings.** Since these don't affect production behavior, we may add new warnings or modify existing warnings in between major versions. In fact, this is what allows us to reliably warn about upcoming breaking changes. * **APIs starting with `unstable_`.** These are provided as experimental features whose APIs we are not yet confident in. By releasing these with an `unstable_` prefix, we can iterate faster and get to a stable API sooner. -* **Alpha and canary versions of React.** We provide alpha versions of React as a way to test new features early, but we need the flexibility to make changes based on what we learn in the alpha period. If you use these versions, note that APIs may change before the stable release. +* **Alpha and Canary versions of React.** We provide alpha versions of React as a way to test new features early, but we need the flexibility to make changes based on what we learn in the alpha period. If you use these versions, note that APIs may change before the stable release. * **Undocumented APIs and internal data structures.** If you access internal property names like `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED` or `__reactInternalInstance$uk43rzhitjg`, there is no warranty. You are on your own. This policy is designed to be pragmatic: certainly, we don't want to cause headaches for you. If we bumped the major version for all of these changes, we would end up releasing more major versions and ultimately causing more versioning pain for the community. It would also mean that we can't make progress in improving React as fast as we'd like. diff --git a/src/content/reference/react-dom/components/input.md b/src/content/reference/react-dom/components/input.md index 7328fddc9..f5685aa6e 100644 --- a/src/content/reference/react-dom/components/input.md +++ b/src/content/reference/react-dom/components/input.md @@ -34,7 +34,7 @@ To display an input, render the [built-in browser ``](https://developer.m -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). +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). diff --git a/src/content/reference/react-dom/hooks/useFormState.md b/src/content/reference/react-dom/hooks/useFormState.md index b2808079c..fc17ac1fd 100644 --- a/src/content/reference/react-dom/hooks/useFormState.md +++ b/src/content/reference/react-dom/hooks/useFormState.md @@ -5,7 +5,7 @@ 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`. +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`. diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index abaa9b6f2..67a06022b 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -5,7 +5,7 @@ canary: true -The `useFormStatus` 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). +The `useFormStatus` 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). diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index b726e67db..bb2fb6d5d 100644 --- a/src/content/reference/react/use.md +++ b/src/content/reference/react/use.md @@ -5,7 +5,7 @@ canary: true -The `use` 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). +The `use` 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). diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 47593a0ae..2095a4198 100644 --- a/src/content/reference/react/useOptimistic.md +++ b/src/content/reference/react/useOptimistic.md @@ -5,7 +5,7 @@ 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). +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). @@ -27,7 +27,7 @@ The `useOptimistic` Hook is currently only available in React's canary and exper ### `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. +`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. From aa0c547cd6b2cc63b53ba3fc57ec009af1353ecb Mon Sep 17 00:00:00 2001 From: Aki Matsumoto <45055030+nonoakij@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:27:35 +0900 Subject: [PATCH 03/17] Fix: incorrect sample code in documentation related to Server action (#6445) * Fix: component not returned * Fix: missing function statement --- .../reference/react-dom/hooks/useFormStatus.md | 2 +- src/content/reference/react/use-server.md | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index 67a06022b..02e48973e 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -38,7 +38,7 @@ function Submit() { return } -export default App() { +export default function App() { return ( diff --git a/src/content/reference/react/use-server.md b/src/content/reference/react/use-server.md index 938efa903..638163369 100644 --- a/src/content/reference/react/use-server.md +++ b/src/content/reference/react/use-server.md @@ -115,11 +115,13 @@ async function requestUsername(formData) { // ... } -export default App() { - - - - +export default function App() { + return ( +
+ + +
+ ); } ``` From 6570e6cd79a16ac3b1a2902632eddab7e6abb9ad Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Thu, 23 Nov 2023 01:44:47 -0800 Subject: [PATCH 04/17] Update useSyncExternalStore.md --- src/content/reference/react/useSyncExternalStore.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useSyncExternalStore.md b/src/content/reference/react/useSyncExternalStore.md index cda2ec3fa..c557eb90e 100644 --- a/src/content/reference/react/useSyncExternalStore.md +++ b/src/content/reference/react/useSyncExternalStore.md @@ -57,7 +57,7 @@ The current snapshot of the store which you can use in your rendering logic. * If a different `subscribe` function is passed during a re-render, React will re-subscribe to the store using the newly passed `subscribe` function. You can prevent this by declaring `subscribe` outside the component. -* If the store is mutated during a [non-blocking transition update](/reference/react/useTransition), React will fall back to performing that update as blocking. Specifically, React will call `getSnapshot` a second time just before applying changes to the DOM. If it returns a different value than when it was called originally, React will restart the transition update from scratch, this time applying it as a blocking update, to ensure that every component on screen is reflecting the same version of the store. +* If the store is mutated during a [non-blocking transition update](/reference/react/useTransition), React will fall back to performing that update as blocking. Specifically, for every transition update, React will call `getSnapshot` a second time just before applying changes to the DOM. If it returns a different value than when it was called originally, React will restart the update from scratch, this time applying it as a blocking update, to ensure that every component on screen is reflecting the same version of the store. * It's not recommended to _suspend_ a render based on a store value returned by `useSyncExternalStore`. The reason is that mutations to the external store cannot be [marked as non-blocking transition updates](/reference/react/useTransition), so they will trigger the nearest [`Suspense` fallback](/reference/react/Suspense), replacing already-rendered content on screen with a loading spinner, which typically makes a poor UX. From 943e3ce4e52be56bcd75b679448847302f557da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xuan=20Huang=20=28=E9=BB=84=E7=8E=84=29?= Date: Thu, 30 Nov 2023 13:13:12 +0800 Subject: [PATCH 05/17] Captailize "Strict Mode" (#6426) Summary of changes: There is one "TypeScript strict mode" that is kept unchanged. Co-authored-by: xuan.huang --- src/content/reference/react/StrictMode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index b7ca2227c..e7aa45ac7 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -95,7 +95,7 @@ Strict Mode enables the following checks in development: --- -### Enabling strict mode for a part of the app {/*enabling-strict-mode-for-a-part-of-the-app*/} +### Enabling Strict Mode for a part of the app {/*enabling-strict-mode-for-a-part-of-the-app*/} You can also enable Strict Mode for any part of your application: From b1c4b4e6de827dbbe5e0f759f00b5f8edb7b800c Mon Sep 17 00:00:00 2001 From: Xiao Chuan Date: Wed, 6 Dec 2023 00:34:18 +0800 Subject: [PATCH 06/17] useId add server rendering usage and server api add options (#6457) Co-authored-by: Sebastian Silbermann --- .../react-dom/server/renderToNodeStream.md | 3 ++ .../react-dom/server/renderToStaticMarkup.md | 2 + .../server/renderToStaticNodeStream.md | 3 ++ .../react-dom/server/renderToString.md | 3 ++ src/content/reference/react/useId.md | 37 +++++++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/src/content/reference/react-dom/server/renderToNodeStream.md b/src/content/reference/react-dom/server/renderToNodeStream.md index a4ab2e570..fd2464b97 100644 --- a/src/content/reference/react-dom/server/renderToNodeStream.md +++ b/src/content/reference/react-dom/server/renderToNodeStream.md @@ -43,6 +43,9 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to * `reactNode`: A React node you want to render to HTML. For example, a JSX element like ``. +* **optional** `options`: An object for server render. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + #### Returns {/*returns*/} A [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) that outputs an HTML string. diff --git a/src/content/reference/react-dom/server/renderToStaticMarkup.md b/src/content/reference/react-dom/server/renderToStaticMarkup.md index 01ff17ee6..607affd99 100644 --- a/src/content/reference/react-dom/server/renderToStaticMarkup.md +++ b/src/content/reference/react-dom/server/renderToStaticMarkup.md @@ -35,6 +35,8 @@ It will produce non-interactive HTML output of your React components. #### Parameters {/*parameters*/} * `reactNode`: A React node you want to render to HTML. For example, a JSX node like ``. +* **optional** `options`: An object for server render. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. #### Returns {/*returns*/} diff --git a/src/content/reference/react-dom/server/renderToStaticNodeStream.md b/src/content/reference/react-dom/server/renderToStaticNodeStream.md index ec3d58937..47ef74c3c 100644 --- a/src/content/reference/react-dom/server/renderToStaticNodeStream.md +++ b/src/content/reference/react-dom/server/renderToStaticNodeStream.md @@ -37,6 +37,9 @@ The stream will produce non-interactive HTML output of your React components. * `reactNode`: A React node you want to render to HTML. For example, a JSX element like ``. +* **optional** `options`: An object for server render. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. + #### Returns {/*returns*/} A [Node.js Readable Stream](https://nodejs.org/api/stream.html#readable-streams) that outputs an HTML string. The resulting HTML can't be hydrated on the client. diff --git a/src/content/reference/react-dom/server/renderToString.md b/src/content/reference/react-dom/server/renderToString.md index 41bc6a982..e12692943 100644 --- a/src/content/reference/react-dom/server/renderToString.md +++ b/src/content/reference/react-dom/server/renderToString.md @@ -42,6 +42,9 @@ On the client, call [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) to * `reactNode`: A React node you want to render to HTML. For example, a JSX node like ``. +* **optional** `options`: An object for server render. + * **optional** `identifierPrefix`: A string prefix React uses for IDs generated by [`useId`.](/reference/react/useId) Useful to avoid conflicts when using multiple roots on the same page. Must be the same prefix as passed to [`hydrateRoot`.](/reference/react-dom/client/hydrateRoot#parameters) + #### Returns {/*returns*/} An HTML string. diff --git a/src/content/reference/react/useId.md b/src/content/reference/react/useId.md index 96a5e25a2..99d55a6a5 100644 --- a/src/content/reference/react/useId.md +++ b/src/content/reference/react/useId.md @@ -302,3 +302,40 @@ input { margin: 5px; } ``` + +### useId in server rendering {/*useid-in-server-rendering*/} + +Choose a unique id prefix and pass it into the server options and client options. `useId` will return the same id string on server side and client side. The following example selects `react-app1` as the id prefix. + +```js +import { useId } from 'react'; + +function App() { + const id = useId(); + // ... + +``` + +```js +/** + * server side + */ + +import ReactServer from 'react-dom/server'; + +const { pipe } = ReactServer.renderToPipeableStream(, { identifierPrefix: 'react-app1' }); +// ... + +``` + +```js +/** + * client side + */ + +import { hydrateRoot } from 'react-dom/client'; + +const domNode = document.getElementById('root'); +const root = hydrateRoot(domNode, reactNode, { identifierPrefix: 'react-app1' }); + +``` From 4226fbf3bfcd3f48c7ab21053a8f4720a1129251 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 5 Dec 2023 20:17:43 +0000 Subject: [PATCH 07/17] Edits to useId doc (#6464) --- src/content/reference/react/useId.md | 41 ++++++++++++---------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/src/content/reference/react/useId.md b/src/content/reference/react/useId.md index 99d55a6a5..81cb3a30f 100644 --- a/src/content/reference/react/useId.md +++ b/src/content/reference/react/useId.md @@ -303,39 +303,32 @@ input { margin: 5px; } -### useId in server rendering {/*useid-in-server-rendering*/} +--- -Choose a unique id prefix and pass it into the server options and client options. `useId` will return the same id string on server side and client side. The following example selects `react-app1` as the id prefix. +### Using the same ID prefix on the client and the server {/*using-the-same-id-prefix-on-the-client-and-the-server*/} -```js -import { useId } from 'react'; - -function App() { - const id = useId(); - // ... - -``` +If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the `identifierPrefix` you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix` you pass to the [server APIs](https://react.dev/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream) ```js -/** - * server side - */ - -import ReactServer from 'react-dom/server'; - -const { pipe } = ReactServer.renderToPipeableStream(, { identifierPrefix: 'react-app1' }); -// ... +// Server +import { renderToPipeableStream } from 'react-dom/server'; +const { pipe } = renderToPipeableStream( + , + { identifierPrefix: 'react-app1' } +); ``` ```js -/** - * client side - */ - +// Client import { hydrateRoot } from 'react-dom/client'; const domNode = document.getElementById('root'); -const root = hydrateRoot(domNode, reactNode, { identifierPrefix: 'react-app1' }); - +const root = hydrateRoot( + domNode, + reactNode, + { identifierPrefix: 'react-app1' } +); ``` + +You do not need to pass `identifierPrefix` if you only have one React app on the page. From b9bf6664626a0f0f227db2ba7874018fd183644f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 5 Dec 2023 20:19:06 +0000 Subject: [PATCH 08/17] Oops --- src/content/reference/react/useId.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useId.md b/src/content/reference/react/useId.md index 81cb3a30f..6d3c01674 100644 --- a/src/content/reference/react/useId.md +++ b/src/content/reference/react/useId.md @@ -307,7 +307,7 @@ input { margin: 5px; } ### Using the same ID prefix on the client and the server {/*using-the-same-id-prefix-on-the-client-and-the-server*/} -If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the `identifierPrefix` you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix` you pass to the [server APIs](https://react.dev/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream) +If you [render multiple independent React apps on the same page](#specifying-a-shared-prefix-for-all-generated-ids), and some of these apps are server-rendered, make sure that the `identifierPrefix` you pass to the [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) call on the client side is the same as the `identifierPrefix` you pass to the [server APIs](/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream) ```js // Server From ae4be842dd7f464f0e45a1391845dcec5115ad91 Mon Sep 17 00:00:00 2001 From: "Bud (Mugur) Chirica" Date: Wed, 6 Dec 2023 14:53:27 +0000 Subject: [PATCH 09/17] Fix Next JS link (#6467) --- src/content/learn/start-a-new-react-project.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/start-a-new-react-project.md b/src/content/learn/start-a-new-react-project.md index 9c395d3f0..39bd40e5c 100644 --- a/src/content/learn/start-a-new-react-project.md +++ b/src/content/learn/start-a-new-react-project.md @@ -24,7 +24,7 @@ If you want to build a new app or a new website fully with React, we recommend p npx create-next-app@latest -If you're new to Next.js, check out the [Next.js tutorial.](https://nextjs.org/learn/foundations/about-nextjs) +If you're new to Next.js, check out the [Next.js documentation.](https://nextjs.org/docs) Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports a [static export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) which doesn't require a server. From af54fc873819892f6050340df236f33a18ba5fb8 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Thu, 7 Dec 2023 00:34:28 +0200 Subject: [PATCH 10/17] Link to the new Next.js tutorial instead (#6468) --- src/content/learn/start-a-new-react-project.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/start-a-new-react-project.md b/src/content/learn/start-a-new-react-project.md index 39bd40e5c..a98e09669 100644 --- a/src/content/learn/start-a-new-react-project.md +++ b/src/content/learn/start-a-new-react-project.md @@ -24,7 +24,7 @@ If you want to build a new app or a new website fully with React, we recommend p npx create-next-app@latest -If you're new to Next.js, check out the [Next.js documentation.](https://nextjs.org/docs) +If you're new to Next.js, check out the [learn Next.js course.](https://nextjs.org/learn) Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports a [static export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) which doesn't require a server. From bec75ca3487758d82a26ef8253556cdb6f3bfdc9 Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Tue, 12 Dec 2023 22:44:41 -0800 Subject: [PATCH 11/17] Update useSyncExternalStore.md: tweak link this way "cannot be marked" is all the same style and you don't skim the link text and gloss over the "cannot be" --- src/content/reference/react/useSyncExternalStore.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/useSyncExternalStore.md b/src/content/reference/react/useSyncExternalStore.md index c557eb90e..bc54d5460 100644 --- a/src/content/reference/react/useSyncExternalStore.md +++ b/src/content/reference/react/useSyncExternalStore.md @@ -59,7 +59,7 @@ The current snapshot of the store which you can use in your rendering logic. * If the store is mutated during a [non-blocking transition update](/reference/react/useTransition), React will fall back to performing that update as blocking. Specifically, for every transition update, React will call `getSnapshot` a second time just before applying changes to the DOM. If it returns a different value than when it was called originally, React will restart the update from scratch, this time applying it as a blocking update, to ensure that every component on screen is reflecting the same version of the store. -* It's not recommended to _suspend_ a render based on a store value returned by `useSyncExternalStore`. The reason is that mutations to the external store cannot be [marked as non-blocking transition updates](/reference/react/useTransition), so they will trigger the nearest [`Suspense` fallback](/reference/react/Suspense), replacing already-rendered content on screen with a loading spinner, which typically makes a poor UX. +* It's not recommended to _suspend_ a render based on a store value returned by `useSyncExternalStore`. The reason is that mutations to the external store cannot be marked as [non-blocking transition updates](/reference/react/useTransition), so they will trigger the nearest [`Suspense` fallback](/reference/react/Suspense), replacing already-rendered content on screen with a loading spinner, which typically makes a poor UX. For example, the following are discouraged: From e98c3939a7c55e0ba2f0ae5beba3b7a1298b8d23 Mon Sep 17 00:00:00 2001 From: Danilo Woznica Date: Wed, 13 Dec 2023 18:02:16 +0000 Subject: [PATCH 12/17] fix(sandpack-template): use custom react sandpack template (#6484) * fix(sandpack-template): use custom react sandpack template * refactor: Remove console.log statement Remove console.log(filePath); from createFileMap.ts * style: Update file paths in Sandpack components Update file paths in Sandpack components to use root folder and variables --- .../MDX/Sandpack/DownloadButton.tsx | 7 ++- src/components/MDX/Sandpack/SandpackRoot.tsx | 13 +++-- src/components/MDX/Sandpack/createFileMap.ts | 17 ++++-- src/components/MDX/Sandpack/index.tsx | 4 +- src/components/MDX/Sandpack/template.ts | 54 +++++++++++++++++++ 5 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/components/MDX/Sandpack/template.ts diff --git a/src/components/MDX/Sandpack/DownloadButton.tsx b/src/components/MDX/Sandpack/DownloadButton.tsx index d6b1c3299..94cf13ddc 100644 --- a/src/components/MDX/Sandpack/DownloadButton.tsx +++ b/src/components/MDX/Sandpack/DownloadButton.tsx @@ -5,6 +5,7 @@ import {useSyncExternalStore} from 'react'; import {useSandpack} from '@codesandbox/sandpack-react/unstyled'; import {IconDownload} from '../../Icon/IconDownload'; +import {AppJSPath, StylesCSSPath, SUPPORTED_FILES} from './createFileMap'; export interface DownloadButtonProps {} let supportsImportMap = false; @@ -32,8 +33,6 @@ function useSupportsImportMap() { return useSyncExternalStore(subscribe, getCurrentValue, getServerSnapshot); } -const SUPPORTED_FILES = ['/App.js', '/styles.css']; - export function DownloadButton({ providedFiles, }: { @@ -49,8 +48,8 @@ export function DownloadButton({ } const downloadHTML = () => { - const css = sandpack.files['/styles.css']?.code ?? ''; - const code = sandpack.files['/App.js']?.code ?? ''; + const css = sandpack.files[StylesCSSPath]?.code ?? ''; + const code = sandpack.files[AppJSPath]?.code ?? ''; const blob = new Blob([ ` diff --git a/src/components/MDX/Sandpack/SandpackRoot.tsx b/src/components/MDX/Sandpack/SandpackRoot.tsx index df0c757f2..d47fd903c 100644 --- a/src/components/MDX/Sandpack/SandpackRoot.tsx +++ b/src/components/MDX/Sandpack/SandpackRoot.tsx @@ -9,6 +9,7 @@ import {SandpackLogLevel} from '@codesandbox/sandpack-client'; import {CustomPreset} from './CustomPreset'; import {createFileMap} from './createFileMap'; import {CustomTheme} from './Themes'; +import {template} from './template'; type SandpackProps = { children: React.ReactNode; @@ -70,17 +71,19 @@ function SandpackRoot(props: SandpackProps) { const codeSnippets = Children.toArray(children) as React.ReactElement[]; const files = createFileMap(codeSnippets); - files['/styles.css'] = { - code: [sandboxStyle, files['/styles.css']?.code ?? ''].join('\n\n'), - hidden: !files['/styles.css']?.visible, + files['/src/styles.css'] = { + code: [sandboxStyle, files['/src/styles.css']?.code ?? ''].join('\n\n'), + hidden: !files['/src/styles.css']?.visible, }; return (
{ return codeSnippets.reduce( (result: Record, codeSnippet: React.ReactElement) => { @@ -17,7 +27,7 @@ export const createFileMap = (codeSnippets: any) => { if (props.meta) { const [name, ...params] = props.meta.split(' '); - filePath = '/' + name; + filePath = rootFolder + name; if (params.includes('hidden')) { fileHidden = true; } @@ -26,15 +36,16 @@ export const createFileMap = (codeSnippets: any) => { } } else { if (props.className === 'language-js') { - filePath = '/App.js'; + filePath = AppJSPath; } else if (props.className === 'language-css') { - filePath = '/styles.css'; + filePath = StylesCSSPath; } else { throw new Error( `Code block is missing a filename: ${props.children}` ); } } + if (result[filePath]) { throw new Error( `File ${filePath} was defined multiple times. Each file snippet should have a unique path name` diff --git a/src/components/MDX/Sandpack/index.tsx b/src/components/MDX/Sandpack/index.tsx index 6873547a1..6755ba8de 100644 --- a/src/components/MDX/Sandpack/index.tsx +++ b/src/components/MDX/Sandpack/index.tsx @@ -3,7 +3,7 @@ */ import {lazy, memo, Children, Suspense} from 'react'; -import {createFileMap} from './createFileMap'; +import {AppJSPath, createFileMap} from './createFileMap'; const SandpackRoot = lazy(() => import('./SandpackRoot')); @@ -57,7 +57,7 @@ export default memo(function SandpackWrapper(props: any): any { ); let activeCode; if (!activeCodeSnippet.length) { - activeCode = codeSnippet['/App.js'].code; + activeCode = codeSnippet[AppJSPath].code; } else { activeCode = codeSnippet[activeCodeSnippet[0]].code; } diff --git a/src/components/MDX/Sandpack/template.ts b/src/components/MDX/Sandpack/template.ts new file mode 100644 index 000000000..9ead18a14 --- /dev/null +++ b/src/components/MDX/Sandpack/template.ts @@ -0,0 +1,54 @@ +export const template = { + '/src/index.js': { + hidden: true, + code: `import React, { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import "./styles.css"; + +import App from "./App"; + +const root = createRoot(document.getElementById("root")); +root.render( + + + +);`, + }, + '/package.json': { + hidden: true, + code: JSON.stringify( + { + name: 'react.dev', + version: '0.0.0', + main: '/src/index.js', + scripts: { + start: 'react-scripts start', + build: 'react-scripts build', + test: 'react-scripts test --env=jsdom', + eject: 'react-scripts eject', + }, + dependencies: { + react: '^18.0.0', + 'react-dom': '^18.0.0', + 'react-scripts': '^5.0.0', + }, + }, + null, + 2 + ), + }, + '/public/index.html': { + hidden: true, + code: ` + + + + + Document + + +
+ +`, + }, +}; From 01e80fd1413eecd2bfd1415294a3c929cf9211d9 Mon Sep 17 00:00:00 2001 From: Ehtesham Siddiqui Date: Sat, 16 Dec 2023 00:07:27 +0530 Subject: [PATCH 13/17] Add React India 2024 conference (#6481) * feat: add react india 2024 * update: move react india 2024 in date order * update: move conferences to past section * refactor: sort past conferences --- src/content/community/conferences.md | 81 +++++++++++++++------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/src/content/community/conferences.md b/src/content/community/conferences.md index 1c164a098..9f020966e 100644 --- a/src/content/community/conferences.md +++ b/src/content/community/conferences.md @@ -10,72 +10,77 @@ Do you know of a local React.js conference? Add it here! (Please keep the list c ## Upcoming Conferences {/*upcoming-conferences*/} -### RedwoodJS Conference 2023 {/*redwoodjs-conference-2023*/} -September 26 - 29, 2023. Grants Pass, Oregon + remote (hybrid event) - -[Website](https://www.redwoodjsconf.com/) - [Twitter](https://twitter.com/redwoodjs) +### App.js Conf 2024 {/*appjs-conf-2024*/} +May 22 - 24, 2024. In-person in Kraków, Poland + remote -### React Alicante 2023 {/*react-alicante-2023*/} -September 28 - 30, 2023. Alicante, Spain +[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) -[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/reactalicante) +### Render(ATL) 2024 🍑 {/*renderatl-2024-*/} +June 12 - June 14, 2024. Atlanta, GA, USA -### React Live 2023 {/*react-live-2023*/} -September 29, 2023. Amsterdam, Netherlands +[Website](https://renderatl.com) - [Discord](https://www.renderatl.com/discord) - [Twitter](https://twitter.com/renderATL) - [Instagram](https://www.instagram.com/renderatl/) - [Facebook](https://www.facebook.com/renderatl/) - [LinkedIn](https://www.linkedin.com/company/renderatl) - [Podcast](https://www.renderatl.com/culture-and-code#/) -[Website](https://reactlive.nl/) +### React India 2024 {/*react-india-2024*/} +October 17 - 19, 2024. In-person in Goa, India (hybrid event) + Oct 15 2024 - remote day -### React Native EU 2023 {/*react-native-eu-2023*/} -September 7 & 8, 2023. Wrocław, Poland +[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w) -[Website](https://react-native.eu) - [Twitter](https://twitter.com/react_native_eu) - [Facebook](https://www.facebook.com/reactnativeeu) +## Past Conferences {/*past-conferences*/} -### RenderCon Kenya 2023 {/*rendercon-kenya-2023*/} -September 29 - 30, 2023. Nairobi, Kenya +### React Day Berlin 2023 {/*react-day-berlin-2023*/} +December 8 & 12, 2023. In-person in Berlin, Germany + remote first interactivity (hybrid event) -[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA) +[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://portal.gitnation.org/events/react-day-berlin-2023) -### React India 2023 {/*react-india-2023*/} -October 5 - 7, 2023. In-person in Goa, India (hybrid event) + Oct 3 2023 - remote day +### React Summit US 2023 {/*react-summit-us-2023*/} +November 13 & 15, 2023. In-person in New York, US + remote first interactivity (hybrid event) -[Website](https://www.reactindia.io) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w) +[Website](https://reactsummit.us) - [Twitter](https://twitter.com/reactsummit) - [Facebook](https://www.facebook.com/reactamsterdam) - [Videos](https://portal.gitnation.org/events/react-summit-us-2023) -### React Brussels 2023 {/*react-brussels-2023*/} -October 13th 2023. In-person in Brussels, Belgium + Remote (hybrid) +### reactjsday 2023 {/*reactjsday-2023*/} +October 27th 2023. In-person in Verona, Italy and online (hybrid event) -[Website](https://www.react.brussels/) - [Twitter](https://twitter.com/BrusselsReact) +[Website](https://2023.reactjsday.it/) - [Twitter](https://twitter.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp) ### React Advanced 2023 {/*react-advanced-2023*/} October 20 & 23, 2023. In-person in London, UK + remote first interactivity (hybrid event) [Website](https://www.reactadvanced.com/) - [Twitter](https://twitter.com/ReactAdvanced) - [Facebook](https://www.facebook.com/ReactAdvanced) - [Videos](https://portal.gitnation.org/events/react-advanced-conference-2023) -### reactjsday 2023 {/*reactjsday-2023*/} -October 27th 2023. In-person in Verona, Italy and online (hybrid event) +### React Brussels 2023 {/*react-brussels-2023*/} +October 13th 2023. In-person in Brussels, Belgium + Remote (hybrid) -[Website](https://2023.reactjsday.it/) - [Twitter](https://twitter.com/reactjsday) - [Facebook](https://www.facebook.com/GrUSP/) - [YouTube](https://www.youtube.com/c/grusp) +[Website](https://www.react.brussels/) - [Twitter](https://twitter.com/BrusselsReact) -### React Summit US 2023 {/*react-summit-us-2023*/} -November 13 & 15, 2023. In-person in New York, US + remote first interactivity (hybrid event) +### React India 2023 {/*react-india-2023*/} +October 5 - 7, 2023. In-person in Goa, India (hybrid event) + Oct 3 2023 - remote day -[Website](https://reactsummit.us) - [Twitter](https://twitter.com/reactsummit) - [Facebook](https://www.facebook.com/reactamsterdam) - [Videos](https://portal.gitnation.org/events/react-summit-us-2023) +[Website](https://www.reactindia.io) - [Twitter](https://x.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) - [Youtube](https://www.youtube.com/channel/UCaFbHCBkPvVv1bWs_jwYt3w) -### React Day Berlin 2023 {/*react-day-berlin-2023*/} -December 8 & 12, 2023. In-person in Berlin, Germany + remote first interactivity (hybrid event) +### RenderCon Kenya 2023 {/*rendercon-kenya-2023*/} +September 29 - 30, 2023. Nairobi, Kenya -[Website](https://reactday.berlin) - [Twitter](https://twitter.com/reactdayberlin) - [Facebook](https://www.facebook.com/reactdayberlin/) - [Videos](https://portal.gitnation.org/events/react-day-berlin-2023) +[Website](https://rendercon.org/) - [Twitter](https://twitter.com/renderconke) - [LinkedIn](https://www.linkedin.com/company/renderconke/) - [YouTube](https://www.youtube.com/channel/UC0bCcG8gHUL4njDOpQGcMIA) -### App.js Conf 2024 {/*appjs-conf-2024*/} -May 22 - 24, 2024. In-person in Kraków, Poland + remote +### React Live 2023 {/*react-live-2023*/} +September 29, 2023. Amsterdam, Netherlands -[Website](https://appjs.co) - [Twitter](https://twitter.com/appjsconf) +[Website](https://reactlive.nl/) -### Render(ATL) 2024 🍑 {/*renderatl-2024-*/} -June 12 - June 14, 2024. Atlanta, GA, USA +### React Alicante 2023 {/*react-alicante-2023*/} +September 28 - 30, 2023. Alicante, Spain -[Website](https://renderatl.com) - [Discord](https://www.renderatl.com/discord) - [Twitter](https://twitter.com/renderATL) - [Instagram](https://www.instagram.com/renderatl/) - [Facebook](https://www.facebook.com/renderatl/) - [LinkedIn](https://www.linkedin.com/company/renderatl) - [Podcast](https://www.renderatl.com/culture-and-code#/) +[Website](https://reactalicante.es/) - [Twitter](https://twitter.com/reactalicante) -## Past Conferences {/*past-conferences*/} +### RedwoodJS Conference 2023 {/*redwoodjs-conference-2023*/} +September 26 - 29, 2023. Grants Pass, Oregon + remote (hybrid event) + +[Website](https://www.redwoodjsconf.com/) - [Twitter](https://twitter.com/redwoodjs) + +### React Native EU 2023 {/*react-native-eu-2023*/} +September 7 & 8, 2023. Wrocław, Poland + +[Website](https://react-native.eu) - [Twitter](https://twitter.com/react_native_eu) - [Facebook](https://www.facebook.com/reactnativeeu) ### React Rally 2023 🐙 {/*react-rally-2023*/} August 17 & 18, 2023. Salt Lake City, UT, USA From e3c25d1a5f202bada2b0105b91e9a48935414c6c Mon Sep 17 00:00:00 2001 From: Ehtesham Siddiqui Date: Sat, 16 Dec 2023 00:18:30 +0530 Subject: [PATCH 14/17] data: add react mumbai meetup (#6396) --- src/content/community/meetups.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content/community/meetups.md b/src/content/community/meetups.md index 644bbcee3..000eeb43c 100644 --- a/src/content/community/meetups.md +++ b/src/content/community/meetups.md @@ -101,6 +101,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [Bangalore (React Native)](https://www.meetup.com/React-Native-Bangalore-Meetup) * [Chennai](https://www.meetup.com/React-Chennai/) * [Delhi NCR](https://www.meetup.com/React-Delhi-NCR/) +* [Mumbai](https://reactmumbai.dev) * [Pune](https://www.meetup.com/ReactJS-and-Friends/) ## Indonesia {/*indonesia*/} From bb65ace6e0b844561153e0011e20ec317dc2899d Mon Sep 17 00:00:00 2001 From: geeseyj Date: Fri, 15 Dec 2023 15:01:53 -0600 Subject: [PATCH 15/17] Fix #6487 specify which `Sandpack` files go into a `src` directory (#6496) * specify which sandbox files go in src directory * fix some stragglers --- src/components/MDX/Sandpack/createFileMap.ts | 8 +- .../blog/2023/03/16/introducing-react-dev.md | 4 +- .../learn/add-react-to-an-existing-project.md | 4 +- src/content/learn/adding-interactivity.md | 2 +- .../learn/choosing-the-state-structure.md | 62 +++++----- src/content/learn/describing-the-ui.md | 14 +-- src/content/learn/escape-hatches.md | 20 ++-- .../extracting-state-logic-into-a-reducer.md | 106 +++++++++--------- .../importing-and-exporting-components.md | 26 ++--- .../javascript-in-jsx-with-curly-braces.md | 4 +- src/content/learn/keeping-components-pure.md | 38 +++---- .../learn/lifecycle-of-reactive-effects.md | 44 ++++---- src/content/learn/managing-state.md | 32 +++--- .../learn/manipulating-the-dom-with-refs.md | 12 +- .../learn/passing-data-deeply-with-context.md | 56 ++++----- .../learn/passing-props-to-a-component.md | 38 +++---- .../learn/preserving-and-resetting-state.md | 42 +++---- .../queueing-a-series-of-state-updates.md | 8 +- .../learn/reacting-to-input-with-state.md | 14 +-- .../learn/removing-effect-dependencies.md | 48 ++++---- src/content/learn/render-and-commit.md | 12 +- src/content/learn/rendering-lists.md | 50 ++++----- src/content/learn/responding-to-events.md | 8 +- .../learn/reusing-logic-with-custom-hooks.md | 76 ++++++------- .../scaling-up-with-reducer-and-context.md | 46 ++++---- .../learn/separating-events-from-effects.md | 22 ++-- .../learn/sharing-state-between-components.md | 4 +- .../learn/state-a-components-memory.md | 16 +-- .../learn/synchronizing-with-effects.md | 36 +++--- src/content/learn/thinking-in-react.md | 6 +- src/content/learn/tutorial-tic-tac-toe.md | 56 ++++----- src/content/learn/typescript.md | 10 +- .../learn/understanding-your-ui-as-a-tree.md | 22 ++-- src/content/learn/updating-arrays-in-state.md | 30 ++--- .../learn/updating-objects-in-state.md | 24 ++-- .../learn/you-might-not-need-an-effect.md | 22 ++-- .../reference/react-dom/client/createRoot.md | 12 +- .../reference/react-dom/client/hydrateRoot.md | 16 +-- .../reference/react-dom/components/common.md | 8 +- .../reference/react-dom/components/form.md | 18 +-- .../react-dom/components/textarea.md | 2 +- .../reference/react-dom/createPortal.md | 18 +-- .../reference/react-dom/findDOMNode.md | 34 +++--- src/content/reference/react-dom/flushSync.md | 2 +- .../reference/react-dom/hooks/useFormState.md | 12 +- .../react-dom/hooks/useFormStatus.md | 10 +- src/content/reference/react-dom/hydrate.md | 12 +- src/content/reference/react-dom/render.md | 12 +- .../react-dom/unmountComponentAtNode.md | 4 +- src/content/reference/react/Children.md | 30 ++--- src/content/reference/react/Component.md | 18 +-- src/content/reference/react/StrictMode.md | 40 +++---- src/content/reference/react/Suspense.md | 92 +++++++-------- src/content/reference/react/cloneElement.md | 28 ++--- src/content/reference/react/createFactory.md | 10 +- src/content/reference/react/forwardRef.md | 10 +- src/content/reference/react/lazy.md | 6 +- src/content/reference/react/use-client.md | 12 +- src/content/reference/react/use.md | 12 +- src/content/reference/react/useCallback.md | 18 +-- src/content/reference/react/useContext.md | 14 +-- src/content/reference/react/useDebugValue.md | 2 +- .../reference/react/useDeferredValue.md | 22 ++-- src/content/reference/react/useEffect.md | 42 +++---- src/content/reference/react/useId.md | 2 +- .../reference/react/useImperativeHandle.md | 8 +- .../reference/react/useLayoutEffect.md | 24 ++-- src/content/reference/react/useMemo.md | 42 +++---- src/content/reference/react/useOptimistic.md | 4 +- src/content/reference/react/useReducer.md | 20 ++-- src/content/reference/react/useState.md | 14 +-- .../reference/react/useSyncExternalStore.md | 4 +- src/content/reference/react/useTransition.md | 74 ++++++------ 73 files changed, 862 insertions(+), 868 deletions(-) diff --git a/src/components/MDX/Sandpack/createFileMap.ts b/src/components/MDX/Sandpack/createFileMap.ts index 4765f87ed..85c7f09bf 100644 --- a/src/components/MDX/Sandpack/createFileMap.ts +++ b/src/components/MDX/Sandpack/createFileMap.ts @@ -4,12 +4,6 @@ import type {SandpackFile} from '@codesandbox/sandpack-react/unstyled'; -/** - * Ideally, we should update all markdown files and all the sandboxes - * to use the same folder structure to include `src`. However, we can - * do the same by prepending the root folder on this function. - */ -const rootFolder = '/src/'; export const AppJSPath = `/src/App.js`; export const StylesCSSPath = `/src/styles.css`; export const SUPPORTED_FILES = [AppJSPath, StylesCSSPath]; @@ -27,7 +21,7 @@ export const createFileMap = (codeSnippets: any) => { if (props.meta) { const [name, ...params] = props.meta.split(' '); - filePath = rootFolder + name; + filePath = '/' + name; if (params.includes('hidden')) { fileHidden = true; } diff --git a/src/content/blog/2023/03/16/introducing-react-dev.md b/src/content/blog/2023/03/16/introducing-react-dev.md index d2e11fded..4ce209d71 100644 --- a/src/content/blog/2023/03/16/introducing-react-dev.md +++ b/src/content/blog/2023/03/16/introducing-react-dev.md @@ -57,7 +57,7 @@ If you like to learn by doing, we recommend checking out the [Tic-Tac-Toe Tutori -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -175,7 +175,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } diff --git a/src/content/learn/add-react-to-an-existing-project.md b/src/content/learn/add-react-to-an-existing-project.md index 03f491211..f494b0ab1 100644 --- a/src/content/learn/add-react-to-an-existing-project.md +++ b/src/content/learn/add-react-to-an-existing-project.md @@ -67,7 +67,7 @@ Then add these lines of code at the top of your main JavaScript file (it might b ``` -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; // Clear the existing HTML content @@ -131,7 +131,7 @@ This lets you find that HTML element with [`document.getElementById`](https://de ``` -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; function NavigationBar() { diff --git a/src/content/learn/adding-interactivity.md b/src/content/learn/adding-interactivity.md index 501c9f620..d1359d05a 100644 --- a/src/content/learn/adding-interactivity.md +++ b/src/content/learn/adding-interactivity.md @@ -134,7 +134,7 @@ export default function Gallery() { } ``` -```js data.js +```js src/data.js export const sculptureList = [{ name: 'Homenaje a la Neurocirugía', artist: 'Marta Colvin Andrade', diff --git a/src/content/learn/choosing-the-state-structure.md b/src/content/learn/choosing-the-state-structure.md index 49e11a22f..c3218589a 100644 --- a/src/content/learn/choosing-the-state-structure.md +++ b/src/content/learn/choosing-the-state-structure.md @@ -612,7 +612,7 @@ export default function TravelPlan() { } ``` -```js places.js active +```js src/places.js active export const initialTravelPlan = { id: 0, title: '(Root)', @@ -868,7 +868,7 @@ export default function TravelPlan() { } ``` -```js places.js active +```js src/places.js active export const initialTravelPlan = { 0: { id: 0, @@ -1204,7 +1204,7 @@ function PlaceTree({ id, parentId, placesById, onComplete }) { } ``` -```js places.js +```js src/places.js export const initialTravelPlan = { 0: { id: 0, @@ -1543,7 +1543,7 @@ function PlaceTree({ id, parentId, placesById, onComplete }) { } ``` -```js places.js +```js src/places.js export const initialTravelPlan = { 0: { id: 0, @@ -1841,7 +1841,7 @@ This `Clock` component receives two props: `color` and `time`. When you select a -```js Clock.js active +```js src/Clock.js active import { useState } from 'react'; export default function Clock(props) { @@ -1854,7 +1854,7 @@ export default function Clock(props) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import Clock from './Clock.js'; @@ -1896,7 +1896,7 @@ The issue is that this component has `color` state initialized with the initial -```js Clock.js active +```js src/Clock.js active import { useState } from 'react'; export default function Clock(props) { @@ -1908,7 +1908,7 @@ export default function Clock(props) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import Clock from './Clock.js'; @@ -1948,7 +1948,7 @@ Or, using the destructuring syntax: -```js Clock.js active +```js src/Clock.js active import { useState } from 'react'; export default function Clock({ color, time }) { @@ -1960,7 +1960,7 @@ export default function Clock({ color, time }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import Clock from './Clock.js'; @@ -2010,7 +2010,7 @@ Is any state in this example redundant? -```js App.js +```js src/App.js import { useState } from 'react'; import AddItem from './AddItem.js'; import PackingList from './PackingList.js'; @@ -2078,7 +2078,7 @@ export default function TravelPlan() { } ``` -```js AddItem.js hidden +```js src/AddItem.js hidden import { useState } from 'react'; export default function AddItem({ onAddItem }) { @@ -2099,7 +2099,7 @@ export default function AddItem({ onAddItem }) { } ``` -```js PackingList.js hidden +```js src/PackingList.js hidden import { useState } from 'react'; export default function PackingList({ @@ -2149,7 +2149,7 @@ Although you could carefully change each event handler to update the `total` and -```js App.js +```js src/App.js import { useState } from 'react'; import AddItem from './AddItem.js'; import PackingList from './PackingList.js'; @@ -2213,7 +2213,7 @@ export default function TravelPlan() { } ``` -```js AddItem.js hidden +```js src/AddItem.js hidden import { useState } from 'react'; export default function AddItem({ onAddItem }) { @@ -2234,7 +2234,7 @@ export default function AddItem({ onAddItem }) { } ``` -```js PackingList.js hidden +```js src/PackingList.js hidden import { useState } from 'react'; export default function PackingList({ @@ -2290,7 +2290,7 @@ This code works, but there is a minor UI glitch. When you press "Star" or "Unsta -```js App.js +```js src/App.js import { useState } from 'react'; import { initialLetters } from './data.js'; import Letter from './Letter.js'; @@ -2337,7 +2337,7 @@ export default function MailClient() { } ``` -```js Letter.js +```js src/Letter.js export default function Letter({ letter, isHighlighted, @@ -2367,7 +2367,7 @@ export default function Letter({ } ``` -```js data.js +```js src/data.js export const initialLetters = [{ id: 0, subject: 'Ready for adventure?', @@ -2399,7 +2399,7 @@ To fix the issue, remove the duplication from state. Instead of storing *the let -```js App.js +```js src/App.js import { useState } from 'react'; import { initialLetters } from './data.js'; import Letter from './Letter.js'; @@ -2446,7 +2446,7 @@ export default function MailClient() { } ``` -```js Letter.js +```js src/Letter.js export default function Letter({ letter, isHighlighted, @@ -2476,7 +2476,7 @@ export default function Letter({ } ``` -```js data.js +```js src/data.js export const initialLetters = [{ id: 0, subject: 'Ready for adventure?', @@ -2516,7 +2516,7 @@ Instead of a single selected ID, you might want to hold an array or a [Set](http -```js App.js +```js src/App.js import { useState } from 'react'; import { letters } from './data.js'; import Letter from './Letter.js'; @@ -2559,7 +2559,7 @@ export default function MailClient() { } ``` -```js Letter.js +```js src/Letter.js export default function Letter({ letter, onToggle, @@ -2584,7 +2584,7 @@ export default function Letter({ } ``` -```js data.js +```js src/data.js export const letters = [{ id: 0, subject: 'Ready for adventure?', @@ -2615,7 +2615,7 @@ Instead of a single `selectedId`, keep a `selectedIds` *array* in state. For exa -```js App.js +```js src/App.js import { useState } from 'react'; import { letters } from './data.js'; import Letter from './Letter.js'; @@ -2667,7 +2667,7 @@ export default function MailClient() { } ``` -```js Letter.js +```js src/Letter.js export default function Letter({ letter, onToggle, @@ -2692,7 +2692,7 @@ export default function Letter({ } ``` -```js data.js +```js src/data.js export const letters = [{ id: 0, subject: 'Ready for adventure?', @@ -2723,7 +2723,7 @@ To fix this, you can hold a [Set](https://developer.mozilla.org/en-US/docs/Web/J -```js App.js +```js src/App.js import { useState } from 'react'; import { letters } from './data.js'; import Letter from './Letter.js'; @@ -2772,7 +2772,7 @@ export default function MailClient() { } ``` -```js Letter.js +```js src/Letter.js export default function Letter({ letter, onToggle, @@ -2797,7 +2797,7 @@ export default function Letter({ } ``` -```js data.js +```js src/data.js export const letters = [{ id: 0, subject: 'Ready for adventure?', diff --git a/src/content/learn/describing-the-ui.md b/src/content/learn/describing-the-ui.md index 167fe5b70..ce49b85c8 100644 --- a/src/content/learn/describing-the-ui.md +++ b/src/content/learn/describing-the-ui.md @@ -69,7 +69,7 @@ You can declare many components in one file, but large files can get difficult t -```js App.js hidden +```js src/App.js hidden import Gallery from './Gallery.js'; export default function App() { @@ -79,7 +79,7 @@ export default function App() { } ``` -```js Gallery.js active +```js src/Gallery.js active import Profile from './Profile.js'; export default function Gallery() { @@ -94,7 +94,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js export default function Profile() { return ( -```js App.js +```js src/App.js import { people } from './data.js'; import { getImageUrl } from './utils.js'; @@ -398,7 +398,7 @@ export default function List() { } ``` -```js data.js +```js src/data.js export const people = [{ id: 0, name: 'Creola Katherine Johnson', @@ -432,7 +432,7 @@ export const people = [{ }]; ``` -```js utils.js +```js src/utils.js export function getImageUrl(person) { return ( 'https://i.imgur.com/' + diff --git a/src/content/learn/escape-hatches.md b/src/content/learn/escape-hatches.md index 69e733521..23f11f54e 100644 --- a/src/content/learn/escape-hatches.md +++ b/src/content/learn/escape-hatches.md @@ -163,7 +163,7 @@ export default function ChatRoom() { } ``` -```js chat.js +```js src/chat.js export function createConnection() { // A real implementation would actually connect to the server return { @@ -281,7 +281,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -395,7 +395,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server let connectedCallback; @@ -424,7 +424,7 @@ export function createConnection(serverUrl, roomId) { } ``` -```js notifications.js +```js src/notifications.js import Toastify from 'toastify-js'; import 'toastify-js/src/toastify.css'; @@ -528,7 +528,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server let connectedCallback; @@ -557,7 +557,7 @@ export function createConnection(serverUrl, roomId) { } ``` -```js notifications.js hidden +```js src/notifications.js hidden import Toastify from 'toastify-js'; import 'toastify-js/src/toastify.css'; @@ -647,7 +647,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection({ serverUrl, roomId }) { // A real implementation would actually connect to the server return { @@ -721,7 +721,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection({ serverUrl, roomId }) { // A real implementation would actually connect to the server return { @@ -797,7 +797,7 @@ function Dot({ position, opacity }) { } ``` -```js usePointerPosition.js +```js src/usePointerPosition.js import { useState, useEffect } from 'react'; export function usePointerPosition() { @@ -813,7 +813,7 @@ export function usePointerPosition() { } ``` -```js useDelayedValue.js +```js src/useDelayedValue.js import { useState, useEffect } from 'react'; export function useDelayedValue(value, delay) { diff --git a/src/content/learn/extracting-state-logic-into-a-reducer.md b/src/content/learn/extracting-state-logic-into-a-reducer.md index 012a5c3f9..5c08c0123 100644 --- a/src/content/learn/extracting-state-logic-into-a-reducer.md +++ b/src/content/learn/extracting-state-logic-into-a-reducer.md @@ -23,7 +23,7 @@ As your components grow in complexity, it can get harder to see at a glance all -```js App.js +```js src/App.js import { useState } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -79,7 +79,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({onAddTask}) { @@ -103,7 +103,7 @@ export default function AddTask({onAddTask}) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({tasks, onChangeTask, onDeleteTask}) { @@ -398,7 +398,7 @@ You could even use the `reduce()` method with an `initialState` and an array of -```js index.js active +```js src/index.js active import tasksReducer from './tasksReducer.js'; let initialState = []; @@ -415,7 +415,7 @@ const output = document.getElementById('output'); output.textContent = JSON.stringify(finalState, null, 2); ``` -```js tasksReducer.js +```js src/tasksReducer.js export default function tasksReducer(tasks, action) { switch (action.type) { case 'added': { @@ -493,7 +493,7 @@ Now it's fully wired up! Here, the reducer is declared at the bottom of the comp -```js App.js +```js src/App.js import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -574,7 +574,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({onAddTask}) { @@ -598,7 +598,7 @@ export default function AddTask({onAddTask}) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({tasks, onChangeTask, onDeleteTask}) { @@ -678,7 +678,7 @@ If you want, you can even move the reducer to a different file: -```js App.js +```js src/App.js import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -730,7 +730,7 @@ const initialTasks = [ ]; ``` -```js tasksReducer.js +```js src/tasksReducer.js export default function tasksReducer(tasks, action) { switch (action.type) { case 'added': { @@ -762,7 +762,7 @@ export default function tasksReducer(tasks, action) { } ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({onAddTask}) { @@ -786,7 +786,7 @@ export default function AddTask({onAddTask}) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({tasks, onChangeTask, onDeleteTask}) { @@ -889,7 +889,7 @@ Just like with [updating objects](/learn/updating-objects-in-state#write-concise -```js App.js +```js src/App.js import { useImmerReducer } from 'use-immer'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -964,7 +964,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({onAddTask}) { @@ -988,7 +988,7 @@ export default function AddTask({onAddTask}) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({tasks, onChangeTask, onDeleteTask}) { @@ -1126,7 +1126,7 @@ This means that your action object should have a `type: 'changed_selection'`. Yo -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1160,7 +1160,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, message: 'Hello', @@ -1188,7 +1188,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1209,7 +1209,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -1276,7 +1276,7 @@ Here is the example updated to dispatch the corresponding messages: -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1310,7 +1310,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, message: 'Hello', @@ -1338,7 +1338,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1362,7 +1362,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -1420,7 +1420,7 @@ Currently, pressing "Send" doesn't do anything. Add an event handler to the "Sen -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1454,7 +1454,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, message: 'Hello', @@ -1482,7 +1482,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1506,7 +1506,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js active +```js src/Chat.js active import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -1559,7 +1559,7 @@ There are a couple of ways you could do it in the "Send" button event handler. O -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1593,7 +1593,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, message: 'Hello', @@ -1621,7 +1621,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1645,7 +1645,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js active +```js src/Chat.js active import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -1707,7 +1707,7 @@ However, _from the user's perspective_, sending a message is a different action -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1741,7 +1741,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js active +```js src/messengerReducer.js active export const initialState = { selectedId: 0, message: 'Hello', @@ -1775,7 +1775,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1799,7 +1799,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js active +```js src/Chat.js active import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -1904,7 +1904,7 @@ The `[key]: value` [computed property](https://developer.mozilla.org/en-US/docs/ -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -1938,7 +1938,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, message: 'Hello', @@ -1972,7 +1972,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -1996,7 +1996,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -2081,7 +2081,7 @@ Here is the complete solution: -```js App.js +```js src/App.js import { useReducer } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -2115,7 +2115,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, messages: { @@ -2158,7 +2158,7 @@ export function messengerReducer(state, action) { } ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -2182,7 +2182,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -2269,7 +2269,7 @@ Recall that a reducer function takes two arguments--the current state and the ac -```js App.js +```js src/App.js import { useReducer } from './MyReact.js'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -2303,7 +2303,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, messages: { @@ -2346,7 +2346,7 @@ export function messengerReducer(state, action) { } ``` -```js MyReact.js active +```js src/MyReact.js active import { useState } from 'react'; export function useReducer(reducer, initialState) { @@ -2358,7 +2358,7 @@ export function useReducer(reducer, initialState) { } ``` -```js ContactList.js hidden +```js src/ContactList.js hidden export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -2382,7 +2382,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js hidden +```js src/Chat.js hidden import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { @@ -2443,7 +2443,7 @@ Dispatching an action calls a reducer with the current state and the action, and -```js App.js +```js src/App.js import { useReducer } from './MyReact.js'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -2477,7 +2477,7 @@ const contacts = [ ]; ``` -```js messengerReducer.js +```js src/messengerReducer.js export const initialState = { selectedId: 0, messages: { @@ -2520,7 +2520,7 @@ export function messengerReducer(state, action) { } ``` -```js MyReact.js active +```js src/MyReact.js active import { useState } from 'react'; export function useReducer(reducer, initialState) { @@ -2535,7 +2535,7 @@ export function useReducer(reducer, initialState) { } ``` -```js ContactList.js hidden +```js src/ContactList.js hidden export default function ContactList({contacts, selectedId, dispatch}) { return (
@@ -2559,7 +2559,7 @@ export default function ContactList({contacts, selectedId, dispatch}) { } ``` -```js Chat.js hidden +```js src/Chat.js hidden import { useState } from 'react'; export default function Chat({contact, message, dispatch}) { diff --git a/src/content/learn/importing-and-exporting-components.md b/src/content/learn/importing-and-exporting-components.md index 3a39c36db..b458ef402 100644 --- a/src/content/learn/importing-and-exporting-components.md +++ b/src/content/learn/importing-and-exporting-components.md @@ -66,7 +66,7 @@ Here both `Profile` and `Gallery` have been moved out of `App.js` into a new fil -```js App.js +```js src/App.js import Gallery from './Gallery.js'; export default function App() { @@ -76,7 +76,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js function Profile() { return ( -```js App.js +```js src/App.js import Gallery from './Gallery.js'; import { Profile } from './Gallery.js'; @@ -194,7 +194,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js export function Profile() { return ( -```js App.js +```js src/App.js import Gallery from './Gallery.js'; import { Profile } from './Gallery.js'; @@ -281,7 +281,7 @@ export default function App() { } ``` -```js Gallery.js active +```js src/Gallery.js active // Move me to Profile.js! export function Profile() { return ( @@ -304,7 +304,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js ``` ```css @@ -321,7 +321,7 @@ This is the solution with named exports: -```js App.js +```js src/App.js import Gallery from './Gallery.js'; import { Profile } from './Profile.js'; @@ -335,7 +335,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js import { Profile } from './Profile.js'; export default function Gallery() { @@ -350,7 +350,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js export function Profile() { return ( -```js App.js +```js src/App.js import Gallery from './Gallery.js'; import Profile from './Profile.js'; @@ -385,7 +385,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js import Profile from './Profile.js'; export default function Gallery() { @@ -400,7 +400,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js export default function Profile() { return ( -```js App.js +```js src/App.js import { getImageUrl } from './utils.js' const person = { @@ -561,7 +561,7 @@ export default function TodoList() { } ``` -```js utils.js +```js src/utils.js export function getImageUrl(person) { return ( 'https://i.imgur.com/' + diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 60760edc5..6d4f55763 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -49,7 +49,7 @@ React is designed around this concept. **React assumes that every component you -```js App.js +```js src/App.js function Recipe({ drinkers }) { return (
    @@ -243,7 +243,7 @@ Rendering is a *calculation*, it shouldn't try to "do" things. Can you express t -```js Clock.js active +```js src/Clock.js active export default function Clock({ time }) { let hours = time.getHours(); if (hours >= 0 && hours <= 6) { @@ -259,7 +259,7 @@ export default function Clock({ time }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import Clock from './Clock.js'; @@ -305,7 +305,7 @@ You can fix this component by calculating the `className` and including it in th -```js Clock.js active +```js src/Clock.js active export default function Clock({ time }) { let hours = time.getHours(); let className; @@ -322,7 +322,7 @@ export default function Clock({ time }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import Clock from './Clock.js'; @@ -380,7 +380,7 @@ The buggy code is in `Profile.js`. Make sure you read it all from top to bottom! -```js Profile.js +```js src/Profile.js import Panel from './Panel.js'; import { getImageUrl } from './utils.js'; @@ -413,7 +413,7 @@ function Avatar() { } ``` -```js Panel.js hidden +```js src/Panel.js hidden import { useState } from 'react'; export default function Panel({ children }) { @@ -429,7 +429,7 @@ export default function Panel({ children }) { } ``` -```js App.js +```js src/App.js import Profile from './Profile.js'; export default function App() { @@ -448,7 +448,7 @@ export default function App() { } ``` -```js utils.js hidden +```js src/utils.js hidden export function getImageUrl(person, size = 's') { return ( 'https://i.imgur.com/' + @@ -481,7 +481,7 @@ To fix the bug, remove the `currentPerson` variable. Instead, pass all informati -```js Profile.js active +```js src/Profile.js active import Panel from './Panel.js'; import { getImageUrl } from './utils.js'; @@ -511,7 +511,7 @@ function Avatar({ person }) { } ``` -```js Panel.js hidden +```js src/Panel.js hidden import { useState } from 'react'; export default function Panel({ children }) { @@ -527,7 +527,7 @@ export default function Panel({ children }) { } ``` -```js App.js +```js src/App.js import Profile from './Profile.js'; export default function App() { @@ -546,7 +546,7 @@ export default function App() { } ``` -```js utils.js hidden +```js src/utils.js hidden export function getImageUrl(person, size = 's') { return ( 'https://i.imgur.com/' + @@ -583,7 +583,7 @@ You implemented the "Create Story" placeholder by pushing one more fake story at -```js StoryTray.js active +```js src/StoryTray.js active export default function StoryTray({ stories }) { stories.push({ id: 'create', @@ -602,7 +602,7 @@ export default function StoryTray({ stories }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; @@ -683,7 +683,7 @@ The simplest fix is to not touch the array at all, and render "Create Story" sep -```js StoryTray.js active +```js src/StoryTray.js active export default function StoryTray({ stories }) { return (
      @@ -698,7 +698,7 @@ export default function StoryTray({ stories }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; @@ -767,7 +767,7 @@ Alternatively, you could create a _new_ array (by copying the existing one) befo -```js StoryTray.js active +```js src/StoryTray.js active export default function StoryTray({ stories }) { // Copy the array! let storiesToDisplay = stories.slice(); @@ -790,7 +790,7 @@ export default function StoryTray({ stories }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState, useEffect } from 'react'; import StoryTray from './StoryTray.js'; diff --git a/src/content/learn/lifecycle-of-reactive-effects.md b/src/content/learn/lifecycle-of-reactive-effects.md index 5d9554a1a..3dc9a75f0 100644 --- a/src/content/learn/lifecycle-of-reactive-effects.md +++ b/src/content/learn/lifecycle-of-reactive-effects.md @@ -251,7 +251,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -447,7 +447,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -527,7 +527,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -646,7 +646,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -837,7 +837,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -912,7 +912,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -1329,7 +1329,7 @@ Suppressing the linter is always suspicious. Could this be a bug? -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; import { @@ -1374,7 +1374,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { useState, useEffect } from 'react'; export default function ChatRoom({ roomId, createConnection }) { @@ -1389,7 +1389,7 @@ export default function ChatRoom({ roomId, createConnection }) { } ``` -```js chat.js +```js src/chat.js export function createEncryptedConnection(roomId) { // A real implementation would actually connect to the server return { @@ -1427,7 +1427,7 @@ If you remove the linter suppression, you will see a lint error. The problem is -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; import { @@ -1472,7 +1472,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { useState, useEffect } from 'react'; export default function ChatRoom({ roomId, createConnection }) { @@ -1486,7 +1486,7 @@ export default function ChatRoom({ roomId, createConnection }) { } ``` -```js chat.js +```js src/chat.js export function createEncryptedConnection(roomId) { // A real implementation would actually connect to the server return { @@ -1522,7 +1522,7 @@ It is correct that `createConnection` is a dependency. However, this code is a b -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; @@ -1560,7 +1560,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { useState, useEffect } from 'react'; import { createEncryptedConnection, @@ -1581,7 +1581,7 @@ export default function ChatRoom({ roomId, isEncrypted }) { } ``` -```js chat.js +```js src/chat.js export function createEncryptedConnection(roomId) { // A real implementation would actually connect to the server return { @@ -1633,7 +1633,7 @@ If you have two independent synchronization processes, you need to write two sep -```js App.js +```js src/App.js import { useState, useEffect } from 'react'; import { fetchData } from './api.js'; @@ -1687,7 +1687,7 @@ export default function Page() { } ``` -```js api.js hidden +```js src/api.js hidden export function fetchData(url) { if (url === '/planets') { return fetchPlanets(); @@ -1782,7 +1782,7 @@ This is why it makes sense to describe them as two separate Effects. Here's an e -```js App.js +```js src/App.js import { useState, useEffect } from 'react'; import { fetchData } from './api.js'; @@ -1855,7 +1855,7 @@ export default function Page() { } ``` -```js api.js hidden +```js src/api.js hidden export function fetchData(url) { if (url === '/planets') { return fetchPlanets(); @@ -1945,7 +1945,7 @@ Instead, to reduce repetition, you can extract some logic into a custom Hook lik -```js App.js +```js src/App.js import { useState } from 'react'; import { useSelectOptions } from './useSelectOptions.js'; @@ -1991,7 +1991,7 @@ export default function Page() { } ``` -```js useSelectOptions.js +```js src/useSelectOptions.js import { useState, useEffect } from 'react'; import { fetchData } from './api.js'; @@ -2018,7 +2018,7 @@ export function useSelectOptions(url) { } ``` -```js api.js hidden +```js src/api.js hidden export function fetchData(url) { if (url === '/planets') { return fetchPlanets(); diff --git a/src/content/learn/managing-state.md b/src/content/learn/managing-state.md index c88ae3796..93bcc10fd 100644 --- a/src/content/learn/managing-state.md +++ b/src/content/learn/managing-state.md @@ -308,7 +308,7 @@ However, sometimes this is not what you want. In this chat app, typing a message -```js App.js +```js src/App.js import { useState } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -334,7 +334,7 @@ const contacts = [ ]; ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({ selectedContact, contacts, @@ -358,7 +358,7 @@ export default function ContactList({ } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({ contact }) { @@ -403,7 +403,7 @@ React lets you override the default behavior, and *force* a component to reset i -```js App.js +```js src/App.js import { useState } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -429,7 +429,7 @@ const contacts = [ ]; ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({ selectedContact, contacts, @@ -453,7 +453,7 @@ export default function ContactList({ } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({ contact }) { @@ -506,7 +506,7 @@ Components with many state updates spread across many event handlers can get ove -```js App.js +```js src/App.js import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -589,7 +589,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({ onAddTask }) { @@ -610,7 +610,7 @@ export default function AddTask({ onAddTask }) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({ @@ -733,7 +733,7 @@ export default function Page() { } ``` -```js Section.js +```js src/Section.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -749,7 +749,7 @@ export default function Section({ children }) { } ``` -```js Heading.js +```js src/Heading.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -776,7 +776,7 @@ export default function Heading({ children }) { } ``` -```js LevelContext.js +```js src/LevelContext.js import { createContext } from 'react'; export const LevelContext = createContext(0); @@ -807,7 +807,7 @@ With this approach, a parent component with complex state manages it with a redu -```js App.js +```js src/App.js import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; import { TasksProvider } from './TasksContext.js'; @@ -823,7 +823,7 @@ export default function TaskApp() { } ``` -```js TasksContext.js +```js src/TasksContext.js import { createContext, useContext, useReducer } from 'react'; const TasksContext = createContext(null); @@ -888,7 +888,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js +```js src/AddTask.js import { useState, useContext } from 'react'; import { useTasksDispatch } from './TasksContext.js'; @@ -917,7 +917,7 @@ export default function AddTask({ onAddTask }) { let nextId = 3; ``` -```js TaskList.js +```js src/TaskList.js import { useState, useContext } from 'react'; import { useTasks, useTasksDispatch } from './TasksContext.js'; diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index 3e91a7694..3d5cbfd1d 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -1098,7 +1098,7 @@ You'll need `forwardRef` to opt into exposing a DOM node from your own component -```js App.js +```js src/App.js import SearchButton from './SearchButton.js'; import SearchInput from './SearchInput.js'; @@ -1114,7 +1114,7 @@ export default function Page() { } ``` -```js SearchButton.js +```js src/SearchButton.js export default function SearchButton() { return ( ; } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -455,7 +455,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -627,7 +627,7 @@ Your updated code should look like this: -```js App.js +```js src/App.js function Square({ value }) { return ; } @@ -655,7 +655,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -807,7 +807,7 @@ After you've made the above changes, your code will look like this: -```js App.js +```js src/App.js import { useState } from 'react'; function Square() { @@ -850,7 +850,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -988,7 +988,7 @@ And your code should look like this: -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value }) { @@ -1019,7 +1019,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1228,7 +1228,7 @@ This is what your code should look like: -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -1270,7 +1270,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1422,7 +1422,7 @@ Now you can only add `X`'s or `O`'s to empty squares! Here is what your code sho -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -1473,7 +1473,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1524,7 +1524,7 @@ body { Now that the players can take turns, you'll want to show when the game is won and there are no more turns to make. To do this you'll add a helper function called `calculateWinner` that takes an array of 9 squares, checks for a winner and returns `'X'`, `'O'`, or `null` as appropriate. Don't worry too much about the `calculateWinner` function; it's not specific to React: -```js App.js +```js src/App.js export default function Board() { //... } @@ -1594,7 +1594,7 @@ Congratulations! You now have a working tic-tac-toe game. And you've just learne -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -1674,7 +1674,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1872,7 +1872,7 @@ At this point, you've moved the state to live in the `Game` component, and the U -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -1970,7 +1970,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2083,7 +2083,7 @@ You'll fix this error in the next section. -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -2199,7 +2199,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2311,7 +2311,7 @@ const moves = history.map((squares, move) => { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -2428,7 +2428,7 @@ function calculateWinner(squares) { ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2532,7 +2532,7 @@ If you click on any step in the game's history, the tic-tac-toe board should imm -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -2652,7 +2652,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2742,7 +2742,7 @@ Check out the final result here: -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -2860,7 +2860,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index 04c0efc17..ee44ef076 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -72,7 +72,7 @@ export default function MyApp() { } ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` @@ -112,7 +112,7 @@ export default function MyApp() { } ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` @@ -213,7 +213,7 @@ export default function App() { ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` @@ -277,7 +277,7 @@ function MyComponent() { } ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` @@ -400,7 +400,7 @@ export default function Form() { } ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` 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 98f60cea8..f4528b346 100644 --- a/src/content/learn/understanding-your-ui-as-a-tree.md +++ b/src/content/learn/understanding-your-ui-as-a-tree.md @@ -39,7 +39,7 @@ Here is a React app that renders inspirational quotes. -```js App.js +```js src/App.js import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; @@ -57,7 +57,7 @@ export default function App() { ``` -```js FancyText.js +```js src/FancyText.js export default function FancyText({title, text}) { return title ?

      {text}

      @@ -65,7 +65,7 @@ export default function FancyText({title, text}) { } ``` -```js InspirationGenerator.js +```js src/InspirationGenerator.js import * as React from 'react'; import quotes from './quotes'; import FancyText from './FancyText'; @@ -86,13 +86,13 @@ export default function InspirationGenerator({children}) { } ``` -```js Copyright.js +```js src/Copyright.js export default function Copyright({year}) { return

      ©️ {year}

      ; } ``` -```js quotes.js +```js src/quotes.js export default [ "Don’t let yesterday take up too much of today.” — Will Rogers", "Ambition is putting a ladder against the sky.", @@ -149,7 +149,7 @@ We can update the app to conditionally render either an inspirational quote or c -```js App.js +```js src/App.js import FancyText from './FancyText'; import InspirationGenerator from './InspirationGenerator'; import Copyright from './Copyright'; @@ -167,7 +167,7 @@ export default function App() { ``` -```js FancyText.js +```js src/FancyText.js export default function FancyText({title, text}) { return title ?

      {text}

      @@ -175,13 +175,13 @@ export default function FancyText({title, text}) { } ``` -```js Color.js +```js src/Color.js export default function Color({value}) { return
      } ``` -```js InspirationGenerator.js +```js src/InspirationGenerator.js import * as React from 'react'; import inspirations from './inspirations'; import FancyText from './FancyText'; @@ -206,13 +206,13 @@ export default function InspirationGenerator({children}) { } ``` -```js Copyright.js +```js src/Copyright.js export default function Copyright({year}) { return

      ©️ {year}

      ; } ``` -```js inspirations.js +```js src/inspirations.js export default [ {type: 'quote', value: "Don’t let yesterday take up too much of today.” — Will Rogers"}, {type: 'color', value: "#B73636"}, diff --git a/src/content/learn/updating-arrays-in-state.md b/src/content/learn/updating-arrays-in-state.md index 45c6b70dc..ea861931e 100644 --- a/src/content/learn/updating-arrays-in-state.md +++ b/src/content/learn/updating-arrays-in-state.md @@ -1084,7 +1084,7 @@ In this example, all of the event handlers in `App.js` use mutation. As a result -```js App.js +```js src/App.js import { useState } from 'react'; import AddTodo from './AddTodo.js'; import TaskList from './TaskList.js'; @@ -1139,7 +1139,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -1160,7 +1160,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ @@ -1247,7 +1247,7 @@ In `handleAddTodo`, you can use the array spread syntax. In `handleChangeTodo`, -```js App.js +```js src/App.js import { useState } from 'react'; import AddTodo from './AddTodo.js'; import TaskList from './TaskList.js'; @@ -1306,7 +1306,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -1327,7 +1327,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ @@ -1417,7 +1417,7 @@ This is the same example as in the previous challenge. This time, fix the mutati -```js App.js +```js src/App.js import { useState } from 'react'; import { useImmer } from 'use-immer'; import AddTodo from './AddTodo.js'; @@ -1473,7 +1473,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -1494,7 +1494,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ @@ -1599,7 +1599,7 @@ With Immer, you can write code in the mutative fashion, as long as you're only m -```js App.js +```js src/App.js import { useState } from 'react'; import { useImmer } from 'use-immer'; import AddTodo from './AddTodo.js'; @@ -1661,7 +1661,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -1682,7 +1682,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ @@ -1787,7 +1787,7 @@ For example, in this version `handleAddTodo` is implemented by mutating the Imme -```js App.js +```js src/App.js import { useState } from 'react'; import { useImmer } from 'use-immer'; import AddTodo from './AddTodo.js'; @@ -1846,7 +1846,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -1867,7 +1867,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ diff --git a/src/content/learn/updating-objects-in-state.md b/src/content/learn/updating-objects-in-state.md index 9289f2454..923e4e181 100644 --- a/src/content/learn/updating-objects-in-state.md +++ b/src/content/learn/updating-objects-in-state.md @@ -986,7 +986,7 @@ If something unexpected changes, there is a mutation. Find the mutation in `App. -```js App.js +```js src/App.js import { useState } from 'react'; import Background from './Background.js'; import Box from './Box.js'; @@ -1039,7 +1039,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1102,7 +1102,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1136,7 +1136,7 @@ The fix is to remove the mutation from `handleMove`, and use the spread syntax t -```js App.js +```js src/App.js import { useState } from 'react'; import Background from './Background.js'; import Box from './Box.js'; @@ -1194,7 +1194,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1257,7 +1257,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1291,7 +1291,7 @@ This is the same buggy example as in the previous challenge. This time, fix the -```js App.js +```js src/App.js import { useState } from 'react'; import { useImmer } from 'use-immer'; import Background from './Background.js'; @@ -1345,7 +1345,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1408,7 +1408,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1458,7 +1458,7 @@ This is the solution rewritten with Immer. Notice how the event handlers are wri -```js App.js +```js src/App.js import { useImmer } from 'use-immer'; import Background from './Background.js'; import Box from './Box.js'; @@ -1512,7 +1512,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1575,7 +1575,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { diff --git a/src/content/learn/you-might-not-need-an-effect.md b/src/content/learn/you-might-not-need-an-effect.md index a3b33d3a7..66cdc3117 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -882,7 +882,7 @@ function NewTodo({ onAdd }) { } ``` -```js todos.js +```js src/todos.js let nextId = 0; export function createTodo(text, completed = false) { @@ -975,7 +975,7 @@ function NewTodo({ onAdd }) { } ``` -```js todos.js +```js src/todos.js let nextId = 0; export function createTodo(text, completed = false) { @@ -1061,7 +1061,7 @@ export default function TodoList() { } ``` -```js todos.js +```js src/todos.js let nextId = 0; let calls = 0; @@ -1144,7 +1144,7 @@ export default function TodoList() { } ``` -```js todos.js +```js src/todos.js let nextId = 0; let calls = 0; @@ -1233,7 +1233,7 @@ function NewTodo({ onAdd }) { } ``` -```js todos.js +```js src/todos.js let nextId = 0; let calls = 0; @@ -1278,7 +1278,7 @@ When you select a contact with the buttons at the top, the form resets to reflec -```js App.js hidden +```js src/App.js hidden import { useState } from 'react'; import ContactList from './ContactList.js'; import EditContact from './EditContact.js'; @@ -1330,7 +1330,7 @@ const initialContacts = [ ]; ``` -```js ContactList.js hidden +```js src/ContactList.js hidden export default function ContactList({ contacts, selectedId, @@ -1357,7 +1357,7 @@ export default function ContactList({ } ``` -```js EditContact.js active +```js src/EditContact.js active import { useState, useEffect } from 'react'; export default function EditContact({ savedContact, onSave }) { @@ -1442,7 +1442,7 @@ Split the `EditContact` component in two. Move all the form state into the inner -```js App.js hidden +```js src/App.js hidden import { useState } from 'react'; import ContactList from './ContactList.js'; import EditContact from './EditContact.js'; @@ -1494,7 +1494,7 @@ const initialContacts = [ ]; ``` -```js ContactList.js hidden +```js src/ContactList.js hidden export default function ContactList({ contacts, selectedId, @@ -1521,7 +1521,7 @@ export default function ContactList({ } ``` -```js EditContact.js active +```js src/EditContact.js active import { useState } from 'react'; export default function EditContact(props) { diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index d91bc20c6..afddb4177 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -153,7 +153,7 @@ Usually, you only need to run this code once at startup. It will: ``` -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; import App from './App.js'; import './styles.css'; @@ -162,7 +162,7 @@ const root = createRoot(document.getElementById('root')); root.render(); ``` -```js App.js +```js src/App.js import { useState } from 'react'; export default function App() { @@ -232,7 +232,7 @@ Here, two different React components are rendered into two DOM nodes defined in ``` -```js index.js active +```js src/index.js active import './styles.css'; import { createRoot } from 'react-dom/client'; import { Comments, Navigation } from './Components.js'; @@ -246,7 +246,7 @@ const commentRoot = createRoot(commentDomNode); commentRoot.render(); ``` -```js Components.js +```js src/Components.js export function Navigation() { return (
        @@ -313,7 +313,7 @@ You can call `render` more than once on the same root. As long as the component -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; import './styles.css'; import App from './App.js'; @@ -327,7 +327,7 @@ setInterval(() => { }, 1000); ``` -```js App.js +```js src/App.js export default function App({counter}) { return ( <> diff --git a/src/content/reference/react-dom/client/hydrateRoot.md b/src/content/reference/react-dom/client/hydrateRoot.md index cf77a81ac..c137cdda9 100644 --- a/src/content/reference/react-dom/client/hydrateRoot.md +++ b/src/content/reference/react-dom/client/hydrateRoot.md @@ -143,7 +143,7 @@ To hydrate your app, React will "attach" your components' logic to the initial g

        Hello, world!

        ``` -```js index.js active +```js src/index.js active import './styles.css'; import { hydrateRoot } from 'react-dom/client'; import App from './App.js'; @@ -154,7 +154,7 @@ hydrateRoot( ); ``` -```js App.js +```js src/App.js import { useState } from 'react'; export default function App() { @@ -248,7 +248,7 @@ To silence hydration warnings on an element, add `suppressHydrationWarning={true

        Current Date: 01/01/2020

        ``` -```js index.js +```js src/index.js import './styles.css'; import { hydrateRoot } from 'react-dom/client'; import App from './App.js'; @@ -256,7 +256,7 @@ import App from './App.js'; hydrateRoot(document.getElementById('root'), ); ``` -```js App.js active +```js src/App.js active export default function App() { return (

        @@ -286,7 +286,7 @@ If you intentionally need to render something different on the server and the cl

        Is Server

        ``` -```js index.js +```js src/index.js import './styles.css'; import { hydrateRoot } from 'react-dom/client'; import App from './App.js'; @@ -294,7 +294,7 @@ import App from './App.js'; hydrateRoot(document.getElementById('root'), ); ``` -```js App.js active +```js src/App.js active import { useState, useEffect } from "react"; export default function App() { @@ -340,7 +340,7 @@ If you call `root.render` at some point after hydration, and the component tree

        Hello, world! 0

        ``` -```js index.js active +```js src/index.js active import { hydrateRoot } from 'react-dom/client'; import './styles.css'; import App from './App.js'; @@ -357,7 +357,7 @@ setInterval(() => { }, 1000); ``` -```js App.js +```js src/App.js export default function App({counter}) { return ( <> diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index 78d2713bc..11719112e 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -771,7 +771,7 @@ In the above example, `style={{}}` is not a special syntax, but a regular `{}` o -```js App.js +```js src/App.js import Avatar from './Avatar.js'; const user = { @@ -785,7 +785,7 @@ export default function App() { } ``` -```js Avatar.js active +```js src/Avatar.js active export default function Avatar({ user }) { return ( -```js App.js +```js src/App.js export default function Search() { function search(formData) { const query = formData.get("query"); @@ -146,7 +146,7 @@ Here, we use the `pending` property to indicate the form is submitting. -```js App.js +```js src/App.js import { useFormStatus } from "react-dom"; import { submitForm } from "./actions.js"; @@ -172,7 +172,7 @@ export default function App() { } ``` -```js actions.js hidden +```js src/actions.js hidden export async function submitForm(query) { await new Promise((res) => setTimeout(res, 1000)); } @@ -201,7 +201,7 @@ For example, when a user types a message into the form and hits the "Send" butto -```js App.js +```js src/App.js import { useOptimistic, useState, useRef } from "react"; import { deliverMessage } from "./actions.js"; @@ -251,7 +251,7 @@ export default function App() { } ``` -```js actions.js +```js src/actions.js export async function deliverMessage(message) { await new Promise((res) => setTimeout(res, 1000)); return message; @@ -282,7 +282,7 @@ In some cases the function called by a ``'s `action` prop throw an error. -```js App.js +```js src/App.js import { ErrorBoundary } from "react-error-boundary"; export default function Search() { @@ -330,7 +330,7 @@ Displaying a form submission error message before the JavaScript bundle loads fo -```js App.js +```js src/App.js import { useFormState } from "react-dom"; import { signUpNewUser } from "./api"; @@ -361,7 +361,7 @@ export default function Page() { } ``` -```js api.js hidden +```js src/api.js hidden let emails = []; export async function signUpNewUser(newEmail) { @@ -396,7 +396,7 @@ When a user taps a specific button, the form is submitted, and a corresponding a -```js App.js +```js src/App.js export default function Search() { function publish(formData) { const content = formData.get("content"); diff --git a/src/content/reference/react-dom/components/textarea.md b/src/content/reference/react-dom/components/textarea.md index 5c742f293..2639fcd73 100644 --- a/src/content/reference/react-dom/components/textarea.md +++ b/src/content/reference/react-dom/components/textarea.md @@ -294,7 +294,7 @@ export default function MarkdownEditor() { } ``` -```js MarkdownPreview.js +```js src/MarkdownPreview.js import { Remarkable } from 'remarkable'; const md = new Remarkable(); diff --git a/src/content/reference/react-dom/createPortal.md b/src/content/reference/react-dom/createPortal.md index 006f78a9a..0107c20d3 100644 --- a/src/content/reference/react-dom/createPortal.md +++ b/src/content/reference/react-dom/createPortal.md @@ -137,7 +137,7 @@ In this example, the two containers have styles that disrupt the modal dialog, b -```js App.js active +```js src/App.js active import NoPortalExample from './NoPortalExample'; import PortalExample from './PortalExample'; @@ -155,7 +155,7 @@ export default function App() { } ``` -```js NoPortalExample.js +```js src/NoPortalExample.js import { useState } from 'react'; import ModalContent from './ModalContent.js'; @@ -174,7 +174,7 @@ export default function NoPortalExample() { } ``` -```js PortalExample.js active +```js src/PortalExample.js active import { useState } from 'react'; import { createPortal } from 'react-dom'; import ModalContent from './ModalContent.js'; @@ -195,7 +195,7 @@ export default function PortalExample() { } ``` -```js ModalContent.js +```js src/ModalContent.js export default function ModalContent({ onClose }) { return (
        @@ -207,7 +207,7 @@ export default function ModalContent({ onClose }) { ``` -```css styles.css +```css src/styles.css .clipping-container { position: relative; border: 1px solid #aaa; @@ -269,7 +269,7 @@ Portals can be useful if your React root is only part of a static or server-rend ``` -```js index.js +```js src/index.js import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import App from './App.js'; @@ -283,7 +283,7 @@ root.render( ); ``` -```js App.js active +```js src/App.js active import { createPortal } from 'react-dom'; const sidebarContentEl = document.getElementById('sidebar-content'); @@ -398,7 +398,7 @@ Here is a complete example you can play with: } ``` -```js App.js +```js src/App.js import { useRef, useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import { createMapWidget, addPopupToMapWidget } from './map-widget.js'; @@ -428,7 +428,7 @@ export default function Map() { } ``` -```js map-widget.js +```js src/map-widget.js import 'leaflet/dist/leaflet.css'; import * as L from 'leaflet'; diff --git a/src/content/reference/react-dom/findDOMNode.md b/src/content/reference/react-dom/findDOMNode.md index 75c02c73d..8e7b00653 100644 --- a/src/content/reference/react-dom/findDOMNode.md +++ b/src/content/reference/react-dom/findDOMNode.md @@ -80,7 +80,7 @@ Here, the `input` variable will be set to the `` DOM element. This lets y -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -98,7 +98,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { Component } from 'react'; import { findDOMNode } from 'react-dom'; @@ -128,7 +128,7 @@ Code using `findDOMNode` is fragile because the connection between the JSX node -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -146,7 +146,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { Component } from 'react'; import { findDOMNode } from 'react-dom'; @@ -171,7 +171,7 @@ In this example, `findDOMNode` is no longer used. Instead, `inputRef = createRef -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -189,7 +189,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { createRef, Component } from 'react'; class AutoselectingInput extends Component { @@ -216,7 +216,7 @@ In modern React without class components, the equivalent code would call [`useRe -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -234,7 +234,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { useRef, useEffect } from 'react'; export default function AutoselectingInput() { @@ -261,7 +261,7 @@ In this example, `findDOMNode(this)` finds a DOM node that belongs to another co -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -279,7 +279,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { Component } from 'react'; import { findDOMNode } from 'react-dom'; import MyInput from './MyInput.js'; @@ -297,7 +297,7 @@ class AutoselectingInput extends Component { export default AutoselectingInput; ``` -```js MyInput.js +```js src/MyInput.js export default function MyInput() { return ; } @@ -316,7 +316,7 @@ This version does that, so it no longer needs `findDOMNode`: -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -334,7 +334,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { createRef, Component } from 'react'; import MyInput from './MyInput.js'; @@ -356,7 +356,7 @@ class AutoselectingInput extends Component { export default AutoselectingInput; ``` -```js MyInput.js +```js src/MyInput.js import { forwardRef } from 'react'; const MyInput = forwardRef(function MyInput(props, ref) { @@ -372,7 +372,7 @@ Here is how this code would look like with function components instead of classe -```js App.js +```js src/App.js import { useState } from 'react'; import AutoselectingInput from './AutoselectingInput.js'; @@ -390,7 +390,7 @@ export default function App() { } ``` -```js AutoselectingInput.js active +```js src/AutoselectingInput.js active import { useRef, useEffect } from 'react'; import MyInput from './MyInput.js'; @@ -406,7 +406,7 @@ export default function AutoselectingInput() { } ``` -```js MyInput.js +```js src/MyInput.js import { forwardRef } from 'react'; const MyInput = forwardRef(function MyInput(props, ref) { diff --git a/src/content/reference/react-dom/flushSync.md b/src/content/reference/react-dom/flushSync.md index 7b40a7389..a97d194e4 100644 --- a/src/content/reference/react-dom/flushSync.md +++ b/src/content/reference/react-dom/flushSync.md @@ -83,7 +83,7 @@ For example, the browser `onbeforeprint` API allows you to change the page immed -```js App.js active +```js src/App.js active import { useState, useEffect } from 'react'; import { flushSync } from 'react-dom'; diff --git a/src/content/reference/react-dom/hooks/useFormState.md b/src/content/reference/react-dom/hooks/useFormState.md index fc17ac1fd..bcd431703 100644 --- a/src/content/reference/react-dom/hooks/useFormState.md +++ b/src/content/reference/react-dom/hooks/useFormState.md @@ -121,7 +121,7 @@ To display messages such as an error message or toast that's returned by a Serve -```js App.js +```js src/App.js import { useState } from "react"; import { useFormState } from "react-dom"; import { addToCart } from "./actions.js"; @@ -148,7 +148,7 @@ export default function App() { } ``` -```js actions.js +```js src/actions.js "use server"; export async function addToCart(prevState, queryData) { @@ -161,7 +161,7 @@ export async function addToCart(prevState, queryData) { } ``` -```css styles.css hidden +```css src/styles.css hidden form { border: solid 1px black; margin-bottom: 24px; @@ -194,7 +194,7 @@ The return value from a Server Action can be any serializable value. For example -```js App.js +```js src/App.js import { useState } from "react"; import { useFormState } from "react-dom"; import { addToCart } from "./actions.js"; @@ -230,7 +230,7 @@ export default function App() { } ``` -```js actions.js +```js src/actions.js "use server"; export async function addToCart(prevState, queryData) { @@ -249,7 +249,7 @@ export async function addToCart(prevState, queryData) { } ``` -```css styles.css hidden +```css src/styles.css hidden form { border: solid 1px black; margin-bottom: 24px; diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index 02e48973e..8733ec0ca 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -86,7 +86,7 @@ Here, we use the `pending` property to indicate the form is submitting. -```js App.js +```js src/App.js import { useFormStatus } from "react-dom"; import { submitForm } from "./actions.js"; @@ -112,7 +112,7 @@ export default function App() { } ``` -```js actions.js hidden +```js src/actions.js hidden export async function submitForm(query) { await new Promise((res) => setTimeout(res, 1000)); } @@ -175,7 +175,7 @@ Here, we have a form where users can request a username. We can use `useFormStat -```js UsernameForm.js active +```js src/UsernameForm.js active import {useState, useMemo, useRef} from 'react'; import {useFormStatus} from 'react-dom'; @@ -216,7 +216,7 @@ export default function UsernameForm() { } ``` -```js App.js +```js src/App.js import UsernameForm from './UsernameForm'; import { submitForm } from "./actions.js"; @@ -229,7 +229,7 @@ export default function App() { } ``` -```js actions.js hidden +```js src/actions.js hidden export async function submitForm(query) { await new Promise((res) => setTimeout(res, 1000)); } diff --git a/src/content/reference/react-dom/hydrate.md b/src/content/reference/react-dom/hydrate.md index 639c7ab25..0d1e1cdf9 100644 --- a/src/content/reference/react-dom/hydrate.md +++ b/src/content/reference/react-dom/hydrate.md @@ -88,7 +88,7 @@ In apps fully built with React, **you will usually only hydrate one "root", once

        Hello, world!

        ``` -```js index.js active +```js src/index.js active import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; @@ -96,7 +96,7 @@ import App from './App.js'; hydrate(, document.getElementById('root')); ``` -```js App.js +```js src/App.js export default function App() { return

        Hello, world!

        ; } @@ -126,7 +126,7 @@ To silence hydration warnings on an element, add `suppressHydrationWarning={true

        Current Date: 01/01/2020

        ``` -```js index.js +```js src/index.js import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; @@ -134,7 +134,7 @@ import App from './App.js'; hydrate(, document.getElementById('root')); ``` -```js App.js active +```js src/App.js active export default function App() { return (

        @@ -164,7 +164,7 @@ If you intentionally need to render something different on the server and the cl

        Is Server

        ``` -```js index.js +```js src/index.js import './styles.css'; import { hydrate } from 'react-dom'; import App from './App.js'; @@ -172,7 +172,7 @@ import App from './App.js'; hydrate(, document.getElementById('root')); ``` -```js App.js active +```js src/App.js active import { useState, useEffect } from "react"; export default function App() { diff --git a/src/content/reference/react-dom/render.md b/src/content/reference/react-dom/render.md index a0f751278..03feb2881 100644 --- a/src/content/reference/react-dom/render.md +++ b/src/content/reference/react-dom/render.md @@ -85,7 +85,7 @@ In apps fully built with React, **you will usually only do this once at startup* -```js index.js active +```js src/index.js active import './styles.css'; import { render } from 'react-dom'; import App from './App.js'; @@ -93,7 +93,7 @@ import App from './App.js'; render(, document.getElementById('root')); ``` -```js App.js +```js src/App.js export default function App() { return

        Hello, world!

        ; } @@ -119,7 +119,7 @@ If your page [isn't fully built with React](/learn/add-react-to-an-existing-proj ``` -```js index.js active +```js src/index.js active import './styles.css'; import { render } from 'react-dom'; import { Comments, Navigation } from './Components.js'; @@ -135,7 +135,7 @@ render( ); ``` -```js Components.js +```js src/Components.js export function Navigation() { return (
          @@ -187,7 +187,7 @@ You can call `render` more than once on the same DOM node. As long as the compon -```js index.js active +```js src/index.js active import { render } from 'react-dom'; import './styles.css'; import App from './App.js'; @@ -202,7 +202,7 @@ setInterval(() => { }, 1000); ``` -```js App.js +```js src/App.js export default function App({counter}) { return ( <> diff --git a/src/content/reference/react-dom/unmountComponentAtNode.md b/src/content/reference/react-dom/unmountComponentAtNode.md index 12f11dc74..376a9bc2b 100644 --- a/src/content/reference/react-dom/unmountComponentAtNode.md +++ b/src/content/reference/react-dom/unmountComponentAtNode.md @@ -88,7 +88,7 @@ In this example, clicking "Render React App" will render a React app. Click "Unm ``` -```js index.js active +```js src/index.js active import './styles.css'; import { render, unmountComponentAtNode } from 'react-dom'; import App from './App.js'; @@ -104,7 +104,7 @@ document.getElementById('unmount').addEventListener('click', () => { }); ``` -```js App.js +```js src/App.js export default function App() { return

          Hello, world!

          ; } diff --git a/src/content/reference/react/Children.md b/src/content/reference/react/Children.md index 3683cb7cc..81a28c5b3 100644 --- a/src/content/reference/react/Children.md +++ b/src/content/reference/react/Children.md @@ -33,7 +33,7 @@ const mappedChildren = Children.map(children, child => Call `Children.count(children)` to count the number of children in the `children` data structure. -```js RowList.js active +```js src/RowList.js active import { Children } from 'react'; function RowList({ children }) { @@ -66,7 +66,7 @@ The number of nodes inside these `children`. Call `Children.forEach(children, fn, thisArg?)` to run some code for each child in the `children` data structure. -```js RowList.js active +```js src/RowList.js active import { Children } from 'react'; function SeparatorList({ children }) { @@ -100,7 +100,7 @@ function SeparatorList({ children }) { Call `Children.map(children, fn, thisArg?)` to map or transform each child in the `children` data structure. -```js RowList.js active +```js src/RowList.js active import { Children } from 'react'; function RowList({ children }) { @@ -169,7 +169,7 @@ Otherwise, throws an error. Call `Children.toArray(children)` to create an array out of the `children` data structure. -```js ReversedList.js active +```js src/ReversedList.js active import { Children } from 'react'; export default function ReversedList({ children }) { @@ -258,7 +258,7 @@ export default function App() { } ``` -```js RowList.js active +```js src/RowList.js active import { Children } from 'react'; export default function RowList({ children }) { @@ -336,7 +336,7 @@ function MoreRows() { } ``` -```js RowList.js +```js src/RowList.js import { Children } from 'react'; export default function RowList({ children }) { @@ -395,7 +395,7 @@ export default function App() { } ``` -```js SeparatorList.js active +```js src/SeparatorList.js active import { Children } from 'react'; export default function SeparatorList({ children }) { @@ -439,7 +439,7 @@ export default function App() { } ``` -```js RowList.js active +```js src/RowList.js active import { Children } from 'react'; export default function RowList({ children }) { @@ -510,7 +510,7 @@ export default function App() { } ``` -```js ReversedList.js active +```js src/ReversedList.js active import { Children } from 'react'; export default function ReversedList({ children }) { @@ -572,7 +572,7 @@ export default function App() { } ``` -```js RowList.js +```js src/RowList.js export function RowList({ children }) { return (
          @@ -639,7 +639,7 @@ function MoreRows() { } ``` -```js RowList.js +```js src/RowList.js export function RowList({ children }) { return (
          @@ -698,7 +698,7 @@ export default function App() { } ``` -```js RowList.js +```js src/RowList.js export function RowList({ rows }) { return (
          @@ -761,7 +761,7 @@ export default function App() { } ``` -```js TabSwitcher.js +```js src/TabSwitcher.js import { useState } from 'react'; export default function TabSwitcher({ tabs }) { @@ -817,7 +817,7 @@ export default function App() { } ``` -```js TabSwitcher.js +```js src/TabSwitcher.js import { useState } from 'react'; export default function TabSwitcher({ tabIds, getHeader, renderContent }) { @@ -869,7 +869,7 @@ export default function App() { } ``` -```js RowList.js +```js src/RowList.js import { Fragment } from 'react'; export function RowList({ rowIds, renderRow }) { diff --git a/src/content/reference/react/Component.md b/src/content/reference/react/Component.md index f8884608b..46406ff5e 100644 --- a/src/content/reference/react/Component.md +++ b/src/content/reference/react/Component.md @@ -1221,7 +1221,7 @@ For example, this `ChatRoom` component keeps a chat connection synchronized with -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; @@ -1251,7 +1251,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { Component } from 'react'; import { createConnection } from './chat.js'; @@ -1312,7 +1312,7 @@ export default class ChatRoom extends Component { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -1601,7 +1601,7 @@ Suppose you're converting this `ChatRoom` class component with lifecycle methods -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; @@ -1631,7 +1631,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { Component } from 'react'; import { createConnection } from './chat.js'; @@ -1692,7 +1692,7 @@ export default class ChatRoom extends Component { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -1741,7 +1741,7 @@ This [`useEffect`](/reference/react/useEffect) call is equivalent to the logic i -```js App.js +```js src/App.js import { useState } from 'react'; import ChatRoom from './ChatRoom.js'; @@ -1771,7 +1771,7 @@ export default function App() { } ``` -```js ChatRoom.js active +```js src/ChatRoom.js active import { useState, useEffect } from 'react'; import { createConnection } from './chat.js'; @@ -1801,7 +1801,7 @@ export default function ChatRoom({ roomId }) { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { diff --git a/src/content/reference/react/StrictMode.md b/src/content/reference/react/StrictMode.md index e7aa45ac7..0b64c5ed9 100644 --- a/src/content/reference/react/StrictMode.md +++ b/src/content/reference/react/StrictMode.md @@ -140,7 +140,7 @@ This `StoryTray` component takes an array of `stories` and adds one last "Create -```js index.js +```js src/index.js import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -150,7 +150,7 @@ const root = createRoot(document.getElementById("root")); root.render(); ``` -```js App.js +```js src/App.js import { useState } from 'react'; import StoryTray from './StoryTray.js'; @@ -175,7 +175,7 @@ export default function App() { } ``` -```js StoryTray.js active +```js src/StoryTray.js active export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: 'Create Story' }); @@ -218,7 +218,7 @@ This mistake will become more noticeable if the `StoryTray` component re-renders -```js index.js +```js src/index.js import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -228,7 +228,7 @@ const root = createRoot(document.getElementById('root')); root.render(); ``` -```js App.js +```js src/App.js import { useState } from 'react'; import StoryTray from './StoryTray.js'; @@ -253,7 +253,7 @@ export default function App() { } ``` -```js StoryTray.js active +```js src/StoryTray.js active import { useState } from 'react'; export default function StoryTray({ stories }) { @@ -316,7 +316,7 @@ This would [make the `StoryTray` function pure.](/learn/keeping-components-pure) -```js index.js +```js src/index.js import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -331,7 +331,7 @@ root.render( ); ``` -```js App.js +```js src/App.js import { useState } from 'react'; import StoryTray from './StoryTray.js'; @@ -356,7 +356,7 @@ export default function App() { } ``` -```js StoryTray.js active +```js src/StoryTray.js active export default function StoryTray({ stories }) { const items = stories; items.push({ id: 'create', label: 'Create Story' }); @@ -397,7 +397,7 @@ li { -```js index.js +```js src/index.js import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -412,7 +412,7 @@ root.render( ); ``` -```js App.js +```js src/App.js import { useState } from 'react'; import StoryTray from './StoryTray.js'; @@ -437,7 +437,7 @@ export default function App() { } ``` -```js StoryTray.js active +```js src/StoryTray.js active import { useState } from 'react'; export default function StoryTray({ stories }) { @@ -509,7 +509,7 @@ Consider this example that connects a component to a chat: -```js index.js +```js src/index.js import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -535,7 +535,7 @@ export default function ChatRoom() { } ``` -```js chat.js +```js src/chat.js let connections = 0; export function createConnection(serverUrl, roomId) { @@ -568,7 +568,7 @@ To make the issue more obvious, let's implement a feature. In the example below, -```js index.js +```js src/index.js import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -619,7 +619,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js let connections = 0; export function createConnection(serverUrl, roomId) { @@ -662,7 +662,7 @@ Now that your Effect "cleans up" after itself and destroys the outdated connecti -```js index.js +```js src/index.js import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -693,7 +693,7 @@ export default function ChatRoom() { } ``` -```js chat.js +```js src/chat.js let connections = 0; export function createConnection(serverUrl, roomId) { @@ -726,7 +726,7 @@ Strict Mode lets you notice such mistakes early in the process. When you fix you -```js index.js +```js src/index.js import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -783,7 +783,7 @@ export default function App() { } ``` -```js chat.js +```js src/chat.js let connections = 0; export function createConnection(serverUrl, roomId) { diff --git a/src/content/reference/react/Suspense.md b/src/content/reference/react/Suspense.md index d94003783..4ec3dd7aa 100644 --- a/src/content/reference/react/Suspense.md +++ b/src/content/reference/react/Suspense.md @@ -69,7 +69,7 @@ In the example below, the `Albums` component *suspends* while fetching the list } ``` -```js App.js hidden +```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -94,7 +94,7 @@ export default function App() { } ``` -```js ArtistPage.js active +```js src/ArtistPage.js active import { Suspense } from 'react'; import Albums from './Albums.js'; @@ -114,7 +114,7 @@ function Loading() { } ``` -```js Albums.js hidden +```js src/Albums.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -162,7 +162,7 @@ function use(promise) { } ``` -```js data.js hidden +```js src/data.js hidden // Note: the way you would do data fetching depends on // the framework that you use together with Suspense. // Normally, the caching logic would be inside a framework. @@ -300,7 +300,7 @@ In the example below, both `Biography` and `Albums` fetch some data. However, be } ``` -```js App.js hidden +```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -325,7 +325,7 @@ export default function App() { } ``` -```js ArtistPage.js active +```js src/ArtistPage.js active import { Suspense } from 'react'; import Albums from './Albums.js'; import Biography from './Biography.js'; @@ -350,7 +350,7 @@ function Loading() { } ``` -```js Panel.js +```js src/Panel.js export default function Panel({ children }) { return (
          @@ -360,7 +360,7 @@ export default function Panel({ children }) { } ``` -```js Biography.js hidden +```js src/Biography.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -404,7 +404,7 @@ function use(promise) { } ``` -```js Albums.js hidden +```js src/Albums.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -452,7 +452,7 @@ function use(promise) { } ``` -```js data.js hidden +```js src/data.js hidden // Note: the way you would do data fetching depends on // the framework that you use together with Suspense. // Normally, the caching logic would be inside a framework. @@ -625,7 +625,7 @@ The sequence will be: } ``` -```js App.js hidden +```js src/App.js hidden import { useState } from 'react'; import ArtistPage from './ArtistPage.js'; @@ -650,7 +650,7 @@ export default function App() { } ``` -```js ArtistPage.js active +```js src/ArtistPage.js active import { Suspense } from 'react'; import Albums from './Albums.js'; import Biography from './Biography.js'; @@ -687,7 +687,7 @@ function AlbumsGlimmer() { } ``` -```js Panel.js +```js src/Panel.js export default function Panel({ children }) { return (
          @@ -697,7 +697,7 @@ export default function Panel({ children }) { } ``` -```js Biography.js hidden +```js src/Biography.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -741,7 +741,7 @@ function use(promise) { } ``` -```js Albums.js hidden +```js src/Albums.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -789,7 +789,7 @@ function use(promise) { } ``` -```js data.js hidden +```js src/data.js hidden // Note: the way you would do data fetching depends on // the framework that you use together with Suspense. // Normally, the caching logic would be inside a framework. @@ -944,7 +944,7 @@ In this example, the `SearchResults` component suspends while fetching the searc } ``` -```js App.js +```js src/App.js import { Suspense, useState } from 'react'; import SearchResults from './SearchResults.js'; @@ -964,7 +964,7 @@ export default function App() { } ``` -```js SearchResults.js hidden +```js src/SearchResults.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -1018,7 +1018,7 @@ function use(promise) { } ``` -```js data.js hidden +```js src/data.js hidden // Note: the way you would do data fetching depends on // the framework that you use together with Suspense. // Normally, the caching logic would be inside a framework. @@ -1169,7 +1169,7 @@ Enter `"a"` in the example below, wait for the results to load, and then edit th } ``` -```js App.js +```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; import SearchResults from './SearchResults.js'; @@ -1193,7 +1193,7 @@ export default function App() { } ``` -```js SearchResults.js hidden +```js src/SearchResults.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -1247,7 +1247,7 @@ function use(promise) { } ``` -```js data.js hidden +```js src/data.js hidden // Note: the way you would do data fetching depends on // the framework that you use together with Suspense. // Normally, the caching logic would be inside a framework. @@ -1375,7 +1375,7 @@ When a component suspends, the closest parent Suspense boundary switches to show } ``` -```js App.js +```js src/App.js import { Suspense, useState } from 'react'; import IndexPage from './IndexPage.js'; import ArtistPage from './ArtistPage.js'; @@ -1423,7 +1423,7 @@ function BigSpinner() { } ``` -```js Layout.js +```js src/Layout.js export default function Layout({ children }) { return (
          @@ -1438,7 +1438,7 @@ export default function Layout({ children }) { } ``` -```js IndexPage.js +```js src/IndexPage.js export default function IndexPage({ navigate }) { return ( @@ -88,7 +88,7 @@ This inline syntax is the simplest way to provide types for a component, though -```tsx App.tsx active +```tsx src/App.tsx active interface MyButtonProps { /** The text to display inside the button */ title: string; @@ -170,7 +170,7 @@ The [`useReducer` Hook](/reference/react/useReducer) is a more complex Hook that -```tsx App.tsx active +```tsx src/App.tsx active import {useReducer} from 'react'; interface State { @@ -248,7 +248,7 @@ The type of the value provided by the context is inferred from the value passed -```tsx App.tsx active +```tsx src/App.tsx active import { createContext, useContext, useState } from 'react'; type Theme = "light" | "dark" | "system"; @@ -381,7 +381,7 @@ When working with DOM events in React, the type of the event can often be inferr -```tsx App.tsx active +```tsx src/App.tsx active import { useState } from 'react'; export default function Form() { From 303ecae3dd4c7b570cf18e0115b94188f6aad5a1 Mon Sep 17 00:00:00 2001 From: Prajwal Kulkarni Date: Sat, 16 Dec 2023 19:38:30 +0530 Subject: [PATCH 17/17] Update startTransition.md (#6431) --- src/content/reference/react/startTransition.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/reference/react/startTransition.md b/src/content/reference/react/startTransition.md index 4773d77c7..0aef23fd3 100644 --- a/src/content/reference/react/startTransition.md +++ b/src/content/reference/react/startTransition.md @@ -41,7 +41,7 @@ function TabContainer() { #### Parameters {/*parameters*/} -* `scope`: A function that updates some state by calling one or more [`set` functions.](/reference/react/useState#setstate) React immediately calls `scope` with no parameters and marks all state updates scheduled synchronously during the `scope` function call as transitions. They will be [non-blocking](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](/reference/react/useTransition#preventing-unwanted-loading-indicators) +* `scope`: A function that updates some state by calling one or more [`set` functions.](/reference/react/useState#setstate) React immediately calls `scope` with no arguments and marks all state updates scheduled synchronously during the `scope` function call as transitions. They will be [non-blocking](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) and [will not display unwanted loading indicators.](/reference/react/useTransition#preventing-unwanted-loading-indicators) #### Returns {/*returns*/}