From b1c4b4e6de827dbbe5e0f759f00b5f8edb7b800c Mon Sep 17 00:00:00 2001 From: Xiao Chuan Date: Wed, 6 Dec 2023 00:34:18 +0800 Subject: [PATCH 001/258] 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 002/258] 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 003/258] 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 004/258] 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 005/258] 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 006/258] 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 007/258] 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 008/258] 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 009/258] 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 010/258] 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 (