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/Preview.tsx b/src/components/MDX/Sandpack/Preview.tsx index 059645550..9669e5f4f 100644 --- a/src/components/MDX/Sandpack/Preview.tsx +++ b/src/components/MDX/Sandpack/Preview.tsx @@ -54,7 +54,7 @@ export function Preview({ // When throwing a new Error in Sandpack - we want to disable the dev error dialog // to show the Error Boundary fallback - if (rawError && rawError.message.includes(`throw Error('Example error')`)) { + if (rawError && rawError.message.includes('Example Error:')) { rawError = null; } 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) => { @@ -26,15 +30,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 + + +
+ +`, + }, +}; diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx index 5af169e13..dfc4f6104 100644 --- a/src/components/Seo.tsx +++ b/src/components/Seo.tsx @@ -24,6 +24,7 @@ const deployedTranslations = [ 'es', 'fr', 'ja', + 'tr', // We'll add more languages when they have enough content. // Please DO NOT edit this list without a discussion in the reactjs/react.dev repo. // It must be the same between all translations. 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..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; } @@ -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/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 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*/} 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/learn/add-react-to-an-existing-project.md b/src/content/learn/add-react-to-an-existing-project.md index b6180dfe7..67392f9e7 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 @@ npm install react react-dom ``` -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; // Clear ເນື້ອຫາ HTML ທີ່ມີຢູ່ແລ້ວ @@ -131,7 +131,7 @@ root.render(

Hello, world

); ``` -```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 47060fc6a..a9e48017e 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/conditional-rendering.md b/src/content/learn/conditional-rendering.md index e8242137d..ca857686a 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -626,7 +626,11 @@ export default function PackingList() { ສັງເກດທ່ານຕ້ອງຂຽນ `importance > 0 && ...` ແທນທີ່ຈະເປັນ `importance && ...` ສະນັ້ນຫາກ `importance` ເປັນ `0`, ຜົນລັບຈະບໍ່ສະແດງ `0`! +<<<<<<< HEAD ໃນວິທີການນີ້, ຈະໃຊ້ເງື່ອນໄຂສອງເງື່ອນໄຂແຍກກັນເພື່ອໃສ່ຊ່ອງວ່າງລະຫວ່າງຊື່ ແລະ label. ອີກວິທີໜຶ່ງ, ທ່ານສາມາດໃຊ້ fragment ທີ່ມີຊ່ອງວ່າງນຳໜ້າ: `importance > 0 && <> ...` ຫຼື ເພີ່ມຊ່ອງວ່າງພາຍໃນ `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 && ...`. +>>>>>>> bbb08a5a04b0221137e5d60472fc979747af2954 diff --git a/src/content/learn/describing-the-ui.md b/src/content/learn/describing-the-ui.md index c9250ffb8..be7a0e427 100644 --- a/src/content/learn/describing-the-ui.md +++ b/src/content/learn/describing-the-ui.md @@ -70,7 +70,7 @@ img { margin: 0 10px 10px 0; height: 90px; } -```js App.js hidden +```js src/App.js hidden import Gallery from './Gallery.js'; export default function App() { @@ -80,7 +80,7 @@ export default function App() { } ``` -```js Gallery.js active +```js src/Gallery.js active import Profile from './Profile.js'; export default function Gallery() { @@ -95,7 +95,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'; @@ -399,7 +399,7 @@ export default function List() { } ``` -```js data.js +```js src/data.js export const people = [{ id: 0, name: 'Creola Katherine Johnson', @@ -433,7 +433,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 a8888533f..9c8401ad7 100644 --- a/src/content/learn/importing-and-exporting-components.md +++ b/src/content/learn/importing-and-exporting-components.md @@ -70,7 +70,12 @@ These currently live in a **root component file,** named `App.js` in this exampl ທັງ `Profile` ແລະ `Gallery` ຖືກຍ້າຍອອກຈາກ `App.js` ໄປໃນຟາຍໃໝ່ຊື່ `Gallery.js`. ຕອນນີ້ທ່ານສາມາດປ່ຽນ `App.js` ເພື່ອ import `Gallery` ຈາກ `Gallery.js`: +<<<<<<< HEAD ```js App.js +======= + +```js src/App.js +>>>>>>> bbb08a5a04b0221137e5d60472fc979747af2954 import Gallery from './Gallery.js'; export default function App() { @@ -80,7 +85,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'; @@ -198,7 +203,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'; @@ -286,7 +291,7 @@ export default function App() { } ``` -```js Gallery.js active +```js src/Gallery.js active // Move me to Profile.js! export function Profile() { return ( @@ -309,7 +314,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js ``` ```css @@ -326,7 +331,7 @@ img { margin: 0 10px 10px 0; height: 90px; } -```js App.js +```js src/App.js import Gallery from './Gallery.js'; import { Profile } from './Profile.js'; @@ -340,7 +345,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js import { Profile } from './Profile.js'; export default function Gallery() { @@ -355,7 +360,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'; @@ -390,7 +395,7 @@ export default function App() { } ``` -```js Gallery.js +```js src/Gallery.js import Profile from './Profile.js'; export default function Gallery() { @@ -405,7 +410,7 @@ export default function Gallery() { } ``` -```js Profile.js +```js src/Profile.js export default function Profile() { return ( div > div { padding: 20px; } -```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 83f2fa2e5..0b13bdda6 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -49,7 +49,7 @@ React ໄດ້ຮັບການອອກແບບຕາມແນວຄິດ -```js App.js +```js src/App.js function Recipe({ drinkers }) { return (
    @@ -243,7 +243,7 @@ Component ນີ້ພະຍາຍາມຕັ້ງຄ່າ class CSS ຂອ -```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 @@ body > * { -```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 @@ Code ທີ່ມີ bug ແມ່ນຢູ່ໃນ `Profile.js`. ຢ່າລ -```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 @@ h1 { margin: 5px; font-size: 18px; } -```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 @@ CEO ຂອງບໍລິສັດທ່ານກຳລັງຂໍໃຫ້ທ -```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 @@ li { -```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 @@ li { -```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 abaca6424..097f11087 100644 --- a/src/content/learn/managing-state.md +++ b/src/content/learn/managing-state.md @@ -309,7 +309,7 @@ h3, p { margin: 5px 0px; } -```js App.js +```js src/App.js import { useState } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -335,7 +335,7 @@ const contacts = [ ]; ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({ selectedContact, contacts, @@ -359,7 +359,7 @@ export default function ContactList({ } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({ contact }) { @@ -404,7 +404,7 @@ React ໃຫ້ທ່ານແທນທີ່ພຶດທິກຳເລີ່ -```js App.js +```js src/App.js import { useState } from 'react'; import Chat from './Chat.js'; import ContactList from './ContactList.js'; @@ -430,7 +430,7 @@ const contacts = [ ]; ``` -```js ContactList.js +```js src/ContactList.js export default function ContactList({ selectedContact, contacts, @@ -454,7 +454,7 @@ export default function ContactList({ } ``` -```js Chat.js +```js src/Chat.js import { useState } from 'react'; export default function Chat({ contact }) { @@ -507,7 +507,7 @@ Component ທີ່ມີການອັບເດດ state ເປັນຈຳນ -```js App.js +```js src/App.js import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -590,7 +590,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({ onAddTask }) { @@ -611,7 +611,7 @@ export default function AddTask({ onAddTask }) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({ @@ -734,7 +734,7 @@ export default function Page() { } ``` -```js Section.js +```js src/Section.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -750,7 +750,7 @@ export default function Section({ children }) { } ``` -```js Heading.js +```js src/Heading.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -777,7 +777,7 @@ export default function Heading({ children }) { } ``` -```js LevelContext.js +```js src/LevelContext.js import { createContext } from 'react'; export const LevelContext = createContext(0); @@ -808,7 +808,7 @@ Reducer ຊ່ວຍໃຫ້ທ່ານລວມ logic ການອັບເ -```js App.js +```js src/App.js import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; import { TasksProvider } from './TasksContext.js'; @@ -824,7 +824,7 @@ export default function TaskApp() { } ``` -```js TasksContext.js +```js src/TasksContext.js import { createContext, useContext, useReducer } from 'react'; const TasksContext = createContext(null); @@ -889,7 +889,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js +```js src/AddTask.js import { useState, useContext } from 'react'; import { useTasksDispatch } from './TasksContext.js'; @@ -918,7 +918,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; } @@ -362,11 +362,15 @@ export default function Square() { -/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 `<>...`? +<<<<<<< HEAD Component React ຕ້ອງການ return ໜຶ່ງ JSX element ແລະ ບໍ່ສາມາດສົ່ງ JSX ທີ່ຕິດພັນຫຼາຍອັນເຊັ່ນ ສອງປຸ່ມກົດ. ເພື່ອແກ້ໄຂບັນຫານີ້ທ່ານສາມາດໃຊ້ *fragments* (`<>` ແລະ ``) ເພື່ອລວມ JSX ທີ່ຕິດພັນຫຼາຍອັນດັ່ງນີ້: +======= +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: +>>>>>>> bbb08a5a04b0221137e5d60472fc979747af2954 ```js {3-6} export default function Square() { @@ -456,7 +460,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -628,7 +632,7 @@ code ທີ່ອັບເດດຂອງທ່ານຄວນຄ້າຍຄື -```js App.js +```js src/App.js function Square({ value }) { return ; } @@ -656,7 +660,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -809,7 +813,7 @@ function Square() { -```js App.js +```js src/App.js import { useState } from 'react'; function Square() { @@ -852,7 +856,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -989,7 +993,7 @@ function Square({value}) { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value }) { @@ -1020,7 +1024,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1234,7 +1238,7 @@ code ຂອງທ່ານຄວນເປັນແບບນີ້: -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -1276,7 +1280,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1429,7 +1433,7 @@ function handleClick(i) { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -1480,7 +1484,7 @@ export default function Board() { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1531,7 +1535,7 @@ body { ເມື່ອຜູ້ຫຼິ້ນປ່ຽນກັນຫຼິ້ນໄດ້ແລ້ວ, ທ່ານຈະຕ້ອງການສະແດງໃຫ້ເຫັນວ່າເກມຊະນະຕອນໃດ ແລະ ບໍ່ຕ້ອງປ່ຽນຜຽນກັນອີກຕໍ່ໄປ. ເພື່ອເຮັດສິ່ງນີ້ທ່ານຕ້ອງໄດ້ເພີ່ມ helper ຟັງຊັ່ນຊື່ວ່າ `calculateWinner` ທີ່ໃຊ້ array ຂອງ 9 ສີ່ຫຼ່ຽມ, ກວດຫາຜູ້ຊະນະ ແລະ return `'X'`, `'O'`, ຫຼື `null` ຕາມຄວາມເໝາະສົມ. ບໍ່ຕ້ອງກັງວົນຫຼາຍເກີນໄປກ່ຽວກັບຟັງຊັ່ນ `calculateWinner`; ມັນບໍ່ໄດ້ສະເພາະເຈາະຈົງໃນ React: -```js App.js +```js src/App.js export default function Board() { //... } @@ -1601,7 +1605,7 @@ export default function Board() { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -1681,7 +1685,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -1879,7 +1883,7 @@ export default function Game() { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -1977,7 +1981,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2094,7 +2098,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 }) { @@ -2210,7 +2214,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2326,7 +2330,7 @@ const moves = history.map((squares, move) => { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -2443,7 +2447,7 @@ function calculateWinner(squares) { ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2547,7 +2551,7 @@ export default function Game() { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({value, onSquareClick}) { @@ -2667,7 +2671,7 @@ function calculateWinner(squares) { } ``` -```css styles.css +```css src/styles.css * { box-sizing: border-box; } @@ -2757,7 +2761,7 @@ export default function Game() { -```js App.js +```js src/App.js import { useState } from 'react'; function Square({ value, onSquareClick }) { @@ -2875,7 +2879,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..034ac0d46 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -55,7 +55,7 @@ Taking the [`MyButton` component](/learn#components) from the [Quick Start](/lea -```tsx App.tsx active +```tsx src/App.tsx active function MyButton({ title }: { title: string }) { return ( @@ -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; ``` @@ -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; @@ -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; ``` @@ -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 { @@ -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; ``` @@ -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"; @@ -277,7 +277,7 @@ function MyComponent() { } ``` -```js App.js hidden +```js src/App.js hidden import AppTSX from "./App.tsx"; export default App = AppTSX; ``` @@ -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() { @@ -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..2abf7affc 100644 --- a/src/content/learn/understanding-your-ui-as-a-tree.md +++ b/src/content/learn/understanding-your-ui-as-a-tree.md @@ -22,7 +22,7 @@ React, and many other UI libraries, model UI as a tree. Thinking of your app as Trees are a relationship model between items and UI is often represented using tree structures. For example, browsers use tree structures to model HTML ([DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction)) and CSS ([CSSOM](https://developer.mozilla.org/docs/Web/API/CSS_Object_Model)). Mobile platforms also use trees to represent their view hierarchy. - + React creates a UI tree from your components. In this example, the UI tree is then used to render to the DOM. @@ -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 b772082bf..0aa6d5f07 100644 --- a/src/content/learn/updating-arrays-in-state.md +++ b/src/content/learn/updating-arrays-in-state.md @@ -1084,7 +1084,7 @@ button { margin: 5px; } -```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 @@ ul, li { margin: 0; padding: 0; } -```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 @@ ul, li { margin: 0; padding: 0; } -```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 @@ ul, li { margin: 0; padding: 0; } -```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 @@ ul, li { margin: 0; padding: 0; } -```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 7fa0e8495..90e434d56 100644 --- a/src/content/learn/updating-objects-in-state.md +++ b/src/content/learn/updating-objects-in-state.md @@ -987,7 +987,7 @@ input { margin-left: 5px; margin-bottom: 5px; } -```js App.js +```js src/App.js import { useState } from 'react'; import Background from './Background.js'; import Box from './Box.js'; @@ -1040,7 +1040,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1103,7 +1103,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1137,7 +1137,7 @@ select { margin-bottom: 10px; } -```js App.js +```js src/App.js import { useState } from 'react'; import Background from './Background.js'; import Box from './Box.js'; @@ -1195,7 +1195,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1258,7 +1258,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1292,7 +1292,7 @@ select { margin-bottom: 10px; } -```js App.js +```js src/App.js import { useState } from 'react'; import { useImmer } from 'use-immer'; import Background from './Background.js'; @@ -1346,7 +1346,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1409,7 +1409,7 @@ export default function Box({ } ``` -```js Background.js +```js src/Background.js export default function Background({ position }) { @@ -1459,7 +1459,7 @@ select { margin-bottom: 10px; } -```js App.js +```js src/App.js import { useImmer } from 'use-immer'; import Background from './Background.js'; import Box from './Box.js'; @@ -1513,7 +1513,7 @@ export default function Canvas() { } ``` -```js Box.js +```js src/Box.js import { useState } from 'react'; export default function Box({ @@ -1576,7 +1576,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..610742735 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 ( +The `{__html}` object should be created as close to where the HTML is generated as possible, like the above example does in the `renderMarkdownToHTML` function. This ensures that all raw HTML being used in your code is explicitly marked as such, and that only variables that you expect to contain HTML are passed to `dangerouslySetInnerHTML`. It is not recommended to create the object inline like `
        `. + To see why rendering arbitrary HTML is dangerous, replace the code above with this: ```js {1-4,7,8} diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 25d1ba4e9..7a4b26b3f 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -62,7 +62,7 @@ Pass a function to the `action` prop of form to run the function when the form i -```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/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/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 b2808079c..bcd431703 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`. @@ -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 abaa9b6f2..8733ec0ca 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). @@ -38,7 +38,7 @@ function Submit() { return } -export default App() { +export default function App() { return ( @@ -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/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-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 b7ca2227c..0b64c5ed9 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: @@ -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 ( - +export default function App() { + return ( +
          + + +
          + ); } ``` diff --git a/src/content/reference/react/use.md b/src/content/reference/react/use.md index b726e67db..1cf73b7b1 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). @@ -247,7 +247,7 @@ Because `Message` is wrapped in -```js message.js active +```js src/message.js active "use client"; import { use, Suspense } from "react"; @@ -266,7 +266,7 @@ export function MessageContainer({ messagePromise }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState } from "react"; import { MessageContainer } from "./message.js"; @@ -290,7 +290,7 @@ export default function App() { } ``` -```js index.js hidden +```js src/index.js hidden // TODO: update to import from stable // react instead of canary once the `use` // Hook is in a stable release of React @@ -364,7 +364,7 @@ If you'd like to display an error to your users when a Promise is rejected, you -```js message.js active +```js src/message.js active "use client"; import { use, Suspense } from "react"; @@ -386,7 +386,7 @@ function Message({ messagePromise }) { } ``` -```js App.js hidden +```js src/App.js hidden import { useState } from "react"; import { MessageContainer } from "./message.js"; @@ -410,7 +410,7 @@ export default function App() { } ``` -```js index.js hidden +```js src/index.js hidden // TODO: update to import from stable // react instead of canary once the `use` // Hook is in a stable release of React diff --git a/src/content/reference/react/useCallback.md b/src/content/reference/react/useCallback.md index 63b36a600..93ce700e4 100644 --- a/src/content/reference/react/useCallback.md +++ b/src/content/reference/react/useCallback.md @@ -251,7 +251,7 @@ Next, try toggling the theme. **Thanks to `useCallback` together with [`memo`](/ -```js App.js +```js src/App.js import { useState } from 'react'; import ProductPage from './ProductPage.js'; @@ -278,7 +278,7 @@ export default function App() { } ``` -```js ProductPage.js active +```js src/ProductPage.js active import { useCallback } from 'react'; import ShippingForm from './ShippingForm.js'; @@ -304,7 +304,7 @@ function post(url, data) { } ``` -```js ShippingForm.js +```js src/ShippingForm.js import { memo, useState } from 'react'; const ShippingForm = memo(function ShippingForm({ onSubmit }) { @@ -391,7 +391,7 @@ Unlike in the previous example, toggling the theme is also slow now! This is bec -```js App.js +```js src/App.js import { useState } from 'react'; import ProductPage from './ProductPage.js'; @@ -418,7 +418,7 @@ export default function App() { } ``` -```js ProductPage.js active +```js src/ProductPage.js active import ShippingForm from './ShippingForm.js'; export default function ProductPage({ productId, referrer, theme }) { @@ -443,7 +443,7 @@ function post(url, data) { } ``` -```js ShippingForm.js +```js src/ShippingForm.js import { memo, useState } from 'react'; const ShippingForm = memo(function ShippingForm({ onSubmit }) { @@ -525,7 +525,7 @@ However, here is the same code **with the artificial slowdown removed.** Does th -```js App.js +```js src/App.js import { useState } from 'react'; import ProductPage from './ProductPage.js'; @@ -552,7 +552,7 @@ export default function App() { } ``` -```js ProductPage.js active +```js src/ProductPage.js active import ShippingForm from './ShippingForm.js'; export default function ProductPage({ productId, referrer, theme }) { @@ -577,7 +577,7 @@ function post(url, data) { } ``` -```js ShippingForm.js +```js src/ShippingForm.js import { memo, useState } from 'react'; const ShippingForm = memo(function ShippingForm({ onSubmit }) { diff --git a/src/content/reference/react/useContext.md b/src/content/reference/react/useContext.md index ed231c394..bba445d0d 100644 --- a/src/content/reference/react/useContext.md +++ b/src/content/reference/react/useContext.md @@ -745,7 +745,7 @@ Read a [full walkthrough](/learn/scaling-up-with-reducer-and-context) of this ex -```js App.js +```js src/App.js import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; import { TasksProvider } from './TasksContext.js'; @@ -761,7 +761,7 @@ export default function TaskApp() { } ``` -```js TasksContext.js +```js src/TasksContext.js import { createContext, useContext, useReducer } from 'react'; const TasksContext = createContext(null); @@ -825,7 +825,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js +```js src/AddTask.js import { useState, useContext } from 'react'; import { useTasksDispatch } from './TasksContext.js'; @@ -854,7 +854,7 @@ export default function AddTask() { let nextId = 3; ``` -```js TaskList.js +```js src/TaskList.js import { useState, useContext } from 'react'; import { useTasks, useTasksDispatch } from './TasksContext.js'; @@ -1222,7 +1222,7 @@ export default function Page() { } ``` -```js Section.js +```js src/Section.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -1238,7 +1238,7 @@ export default function Section({ children }) { } ``` -```js Heading.js +```js src/Heading.js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; @@ -1265,7 +1265,7 @@ export default function Heading({ children }) { } ``` -```js LevelContext.js +```js src/LevelContext.js import { createContext } from 'react'; export const LevelContext = createContext(0); diff --git a/src/content/reference/react/useDebugValue.md b/src/content/reference/react/useDebugValue.md index 8826665e7..62db9e6b2 100644 --- a/src/content/reference/react/useDebugValue.md +++ b/src/content/reference/react/useDebugValue.md @@ -80,7 +80,7 @@ export default function App() { } ``` -```js useOnlineStatus.js active +```js src/useOnlineStatus.js active import { useSyncExternalStore, useDebugValue } from 'react'; export function useOnlineStatus() { diff --git a/src/content/reference/react/useDeferredValue.md b/src/content/reference/react/useDeferredValue.md index 74fdab8ae..dcd8f98d0 100644 --- a/src/content/reference/react/useDeferredValue.md +++ b/src/content/reference/react/useDeferredValue.md @@ -112,7 +112,7 @@ In this example, the `SearchResults` component [suspends](/reference/react/Suspe } ``` -```js App.js +```js src/App.js import { Suspense, useState } from 'react'; import SearchResults from './SearchResults.js'; @@ -132,7 +132,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 @@ -186,7 +186,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. @@ -326,7 +326,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'; @@ -347,7 +347,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 @@ -401,7 +401,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. @@ -549,7 +549,7 @@ With this change, as soon as you start typing, the stale result list gets slight } ``` -```js App.js +```js src/App.js import { Suspense, useState, useDeferredValue } from 'react'; import SearchResults from './SearchResults.js'; @@ -576,7 +576,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 @@ -630,7 +630,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. @@ -800,7 +800,7 @@ export default function App() { } ``` -```js SlowList.js +```js src/SlowList.js import { memo } from 'react'; const SlowList = memo(function SlowList({ text }) { @@ -877,7 +877,7 @@ export default function App() { } ``` -```js SlowList.js +```js src/SlowList.js import { memo } from 'react'; const SlowList = memo(function SlowList({ text }) { diff --git a/src/content/reference/react/useEffect.md b/src/content/reference/react/useEffect.md index e6e4da103..d7659c5e9 100644 --- a/src/content/reference/react/useEffect.md +++ b/src/content/reference/react/useEffect.md @@ -193,7 +193,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 { @@ -317,7 +317,7 @@ export default function App() { } ``` -```js animation.js +```js src/animation.js export class FadeInAnimation { constructor(node) { this.node = node; @@ -393,7 +393,7 @@ export default function App() { } ``` -```js ModalDialog.js active +```js src/ModalDialog.js active import { useEffect, useRef } from 'react'; export default function ModalDialog({ isOpen, children }) { @@ -454,7 +454,7 @@ function LongSection() { } ``` -```js Box.js active +```js src/Box.js active import { useRef, useEffect } from 'react'; export default function Box() { @@ -597,7 +597,7 @@ export default function App() { } ``` -```js useChatRoom.js +```js src/useChatRoom.js import { useEffect } from 'react'; import { createConnection } from './chat.js'; @@ -612,7 +612,7 @@ export function useChatRoom({ serverUrl, roomId }) { } ``` -```js chat.js +```js src/chat.js export function createConnection(serverUrl, roomId) { // A real implementation would actually connect to the server return { @@ -669,7 +669,7 @@ export default function App() { } ``` -```js useWindowListener.js +```js src/useWindowListener.js import { useState, useEffect } from 'react'; export function useWindowListener(eventType, listener) { @@ -722,7 +722,7 @@ function LongSection() { } ``` -```js Box.js active +```js src/Box.js active import { useRef, useEffect } from 'react'; import { useIntersectionObserver } from './useIntersectionObserver.js'; @@ -752,7 +752,7 @@ export default function Box() { } ``` -```js useIntersectionObserver.js +```js src/useIntersectionObserver.js import { useState, useEffect } from 'react'; export function useIntersectionObserver(ref) { @@ -810,7 +810,7 @@ For example, if you have a third-party map widget or a video player component wr } ``` -```js App.js +```js src/App.js import { useState } from 'react'; import Map from './Map.js'; @@ -828,7 +828,7 @@ export default function App() { } ``` -```js Map.js active +```js src/Map.js active import { useRef, useEffect } from 'react'; import { MapWidget } from './map-widget.js'; @@ -854,7 +854,7 @@ export default function Map({ zoomLevel }) { } ``` -```js map-widget.js +```js src/map-widget.js import 'leaflet/dist/leaflet.css'; import * as L from 'leaflet'; @@ -926,7 +926,7 @@ Note the `ignore` variable which is initialized to `false`, and is set to `true` -```js App.js +```js src/App.js import { useState, useEffect } from 'react'; import { fetchBio } from './api.js'; @@ -962,7 +962,7 @@ export default function Page() { } ``` -```js api.js hidden +```js src/api.js hidden export async function fetchBio(person) { const delay = person === 'Bob' ? 2000 : 200; return new Promise(resolve => { @@ -979,7 +979,7 @@ You can also rewrite using the [`async` / `await`](https://developer.mozilla.org -```js App.js +```js src/App.js import { useState, useEffect } from 'react'; import { fetchBio } from './api.js'; @@ -1018,7 +1018,7 @@ export default function Page() { } ``` -```js api.js hidden +```js src/api.js hidden export async function fetchBio(person) { const delay = person === 'Bob' ? 2000 : 200; return new Promise(resolve => { @@ -1214,7 +1214,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 { @@ -1295,7 +1295,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 { @@ -1388,7 +1388,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 { @@ -1551,7 +1551,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 { @@ -1661,7 +1661,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 { diff --git a/src/content/reference/react/useId.md b/src/content/reference/react/useId.md index 96a5e25a2..c97120eba 100644 --- a/src/content/reference/react/useId.md +++ b/src/content/reference/react/useId.md @@ -269,7 +269,7 @@ export default function App() { } ``` -```js index.js active +```js src/index.js active import { createRoot } from 'react-dom/client'; import App from './App.js'; import './styles.css'; @@ -302,3 +302,33 @@ 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](/reference/react-dom/server) such as [`renderToPipeableStream`.](/reference/react-dom/server/renderToPipeableStream) + +```js +// Server +import { renderToPipeableStream } from 'react-dom/server'; + +const { pipe } = renderToPipeableStream( + , + { identifierPrefix: 'react-app1' } +); +``` + +```js +// Client +import { hydrateRoot } from 'react-dom/client'; + +const domNode = document.getElementById('root'); +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. diff --git a/src/content/reference/react/useImperativeHandle.md b/src/content/reference/react/useImperativeHandle.md index 12ab715ef..abd93cd4c 100644 --- a/src/content/reference/react/useImperativeHandle.md +++ b/src/content/reference/react/useImperativeHandle.md @@ -133,7 +133,7 @@ export default function Form() { } ``` -```js MyInput.js +```js src/MyInput.js import { forwardRef, useRef, useImperativeHandle } from 'react'; const MyInput = forwardRef(function MyInput(props, ref) { @@ -194,7 +194,7 @@ export default function Page() { } ``` -```js Post.js +```js src/Post.js import { forwardRef, useRef, useImperativeHandle } from 'react'; import CommentList from './CommentList.js'; import AddComment from './AddComment.js'; @@ -227,7 +227,7 @@ export default Post; ``` -```js CommentList.js +```js src/CommentList.js import { forwardRef, useRef, useImperativeHandle } from 'react'; const CommentList = forwardRef(function CommentList(props, ref) { @@ -257,7 +257,7 @@ const CommentList = forwardRef(function CommentList(props, ref) { export default CommentList; ``` -```js AddComment.js +```js src/AddComment.js import { forwardRef, useRef, useImperativeHandle } from 'react'; const AddComment = forwardRef(function AddComment(props, ref) { diff --git a/src/content/reference/react/useLayoutEffect.md b/src/content/reference/react/useLayoutEffect.md index 1b65ce3b5..0d7b04841 100644 --- a/src/content/reference/react/useLayoutEffect.md +++ b/src/content/reference/react/useLayoutEffect.md @@ -149,7 +149,7 @@ export default function App() { } ``` -```js ButtonWithTooltip.js +```js src/ButtonWithTooltip.js import { useState, useRef } from 'react'; import Tooltip from './Tooltip.js'; @@ -185,7 +185,7 @@ export default function ButtonWithTooltip({ tooltipContent, ...rest }) { } ``` -```js Tooltip.js active +```js src/Tooltip.js active import { useRef, useLayoutEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import TooltipContainer from './TooltipContainer.js'; @@ -220,7 +220,7 @@ export default function Tooltip({ children, targetRect }) { } ``` -```js TooltipContainer.js +```js src/TooltipContainer.js export default function TooltipContainer({ children, x, y, contentRef }) { return (
          -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -219,7 +219,7 @@ export default function App() { ``` -```js TodoList.js active +```js src/TodoList.js active import { useMemo } from 'react'; import { filterTodos } from './utils.js' @@ -246,7 +246,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { @@ -307,7 +307,7 @@ Unlike in the previous example, toggling the theme is also slow now! This is bec -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -349,7 +349,7 @@ export default function App() { ``` -```js TodoList.js active +```js src/TodoList.js active import { filterTodos } from './utils.js' export default function TodoList({ todos, theme, tab }) { @@ -372,7 +372,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { @@ -427,7 +427,7 @@ However, here is the same code **with the artificial slowdown removed.** Does th -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -469,7 +469,7 @@ export default function App() { ``` -```js TodoList.js active +```js src/TodoList.js active import { filterTodos } from './utils.js' export default function TodoList({ todos, theme, tab }) { @@ -491,7 +491,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { @@ -651,7 +651,7 @@ Next, try toggling the theme. **Thanks to `useMemo` together with [`memo`](/refe -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -692,7 +692,7 @@ export default function App() { } ``` -```js TodoList.js active +```js src/TodoList.js active import { useMemo } from 'react'; import List from './List.js'; import { filterTodos } from './utils.js' @@ -711,7 +711,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js List.js +```js src/List.js import { memo } from 'react'; const List = memo(function List({ items }) { @@ -738,7 +738,7 @@ const List = memo(function List({ items }) { export default List; ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { @@ -793,7 +793,7 @@ Unlike in the previous example, toggling the theme is also slow now! This is bec -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -834,7 +834,7 @@ export default function App() { } ``` -```js TodoList.js active +```js src/TodoList.js active import List from './List.js'; import { filterTodos } from './utils.js' @@ -849,7 +849,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js List.js +```js src/List.js import { memo } from 'react'; const List = memo(function List({ items }) { @@ -876,7 +876,7 @@ const List = memo(function List({ items }) { export default List; ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { @@ -925,7 +925,7 @@ However, here is the same code **with the artificial slowdown removed.** Does th -```js App.js +```js src/App.js import { useState } from 'react'; import { createTodos } from './utils.js'; import TodoList from './TodoList.js'; @@ -966,7 +966,7 @@ export default function App() { } ``` -```js TodoList.js active +```js src/TodoList.js active import List from './List.js'; import { filterTodos } from './utils.js' @@ -980,7 +980,7 @@ export default function TodoList({ todos, theme, tab }) { } ``` -```js List.js +```js src/List.js import { memo } from 'react'; function List({ items }) { @@ -1001,7 +1001,7 @@ function List({ items }) { export default memo(List); ``` -```js utils.js +```js src/utils.js export function createTodos() { const todos = []; for (let i = 0; i < 50; i++) { diff --git a/src/content/reference/react/useOptimistic.md b/src/content/reference/react/useOptimistic.md index 47593a0ae..0a9a74865 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. @@ -72,7 +72,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"; @@ -122,7 +122,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; diff --git a/src/content/reference/react/useReducer.md b/src/content/reference/react/useReducer.md index 3477660d2..dbd18f6b8 100644 --- a/src/content/reference/react/useReducer.md +++ b/src/content/reference/react/useReducer.md @@ -322,7 +322,7 @@ In this example, the reducer manages an array of tasks. The array needs to be up -```js App.js +```js src/App.js import { useReducer } from 'react'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -405,7 +405,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({ onAddTask }) { @@ -426,7 +426,7 @@ export default function AddTask({ onAddTask }) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({ @@ -515,7 +515,7 @@ If updating arrays and objects without mutation feels tedious, you can use a lib -```js App.js +```js src/App.js import { useImmerReducer } from 'use-immer'; import AddTask from './AddTask.js'; import TaskList from './TaskList.js'; @@ -597,7 +597,7 @@ const initialTasks = [ ]; ``` -```js AddTask.js hidden +```js src/AddTask.js hidden import { useState } from 'react'; export default function AddTask({ onAddTask }) { @@ -618,7 +618,7 @@ export default function AddTask({ onAddTask }) { } ``` -```js TaskList.js hidden +```js src/TaskList.js hidden import { useState } from 'react'; export default function TaskList({ @@ -763,7 +763,7 @@ This example passes the initializer function, so the `createInitialState` functi -```js App.js hidden +```js src/App.js hidden import TodoList from './TodoList.js'; export default function App() { @@ -771,7 +771,7 @@ export default function App() { } ``` -```js TodoList.js active +```js src/TodoList.js active import { useReducer } from 'react'; function createInitialState(username) { @@ -851,7 +851,7 @@ This example **does not** pass the initializer function, so the `createInitialSt -```js App.js hidden +```js src/App.js hidden import TodoList from './TodoList.js'; export default function App() { @@ -859,7 +859,7 @@ export default function App() { } ``` -```js TodoList.js active +```js src/TodoList.js active import { useReducer } from 'react'; function createInitialState(username) { diff --git a/src/content/reference/react/useState.md b/src/content/reference/react/useState.md index d23fa489b..ee86f0e8f 100644 --- a/src/content/reference/react/useState.md +++ b/src/content/reference/react/useState.md @@ -630,7 +630,7 @@ In this example, the `todos` state variable holds an array. Each button handler -```js App.js +```js src/App.js import { useState } from 'react'; import AddTodo from './AddTodo.js'; import TaskList from './TaskList.js'; @@ -687,7 +687,7 @@ export default function TaskApp() { } ``` -```js AddTodo.js +```js src/AddTodo.js import { useState } from 'react'; export default function AddTodo({ onAddTodo }) { @@ -708,7 +708,7 @@ export default function AddTodo({ onAddTodo }) { } ``` -```js TaskList.js +```js src/TaskList.js import { useState } from 'react'; export default function TaskList({ @@ -1028,7 +1028,7 @@ Read [preserving and resetting state](/learn/preserving-and-resetting-state) to -```js App.js +```js src/App.js import { useState } from 'react'; export default function App() { @@ -1083,7 +1083,7 @@ In the rare case that none of these apply, there is a pattern you can use to upd Here's an example. This `CountLabel` component displays the `count` prop passed to it: -```js CountLabel.js +```js src/CountLabel.js export default function CountLabel({ count }) { return

          {count}

          } @@ -1093,7 +1093,7 @@ Say you want to show whether the counter has *increased or decreased* since the -```js App.js +```js src/App.js import { useState } from 'react'; import CountLabel from './CountLabel.js'; @@ -1113,7 +1113,7 @@ export default function App() { } ``` -```js CountLabel.js active +```js src/CountLabel.js active import { useState } from 'react'; export default function CountLabel({ count }) { diff --git a/src/content/reference/react/useSyncExternalStore.md b/src/content/reference/react/useSyncExternalStore.md index cda2ec3fa..ebaf0987b 100644 --- a/src/content/reference/react/useSyncExternalStore.md +++ b/src/content/reference/react/useSyncExternalStore.md @@ -57,9 +57,9 @@ 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. +* 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: @@ -131,7 +131,7 @@ export default function TodosApp() { } ``` -```js todoStore.js +```js src/todoStore.js // This is an example of a third-party store // that you might need to integrate with React. @@ -300,7 +300,7 @@ export default function App() { } ``` -```js useOnlineStatus.js +```js src/useOnlineStatus.js import { useSyncExternalStore } from 'react'; export function useOnlineStatus() { diff --git a/src/content/reference/react/useTransition.md b/src/content/reference/react/useTransition.md index 672b448b6..49df279fb 100644 --- a/src/content/reference/react/useTransition.md +++ b/src/content/reference/react/useTransition.md @@ -184,7 +184,7 @@ export default function TabContainer() { } ``` -```js TabButton.js +```js src/TabButton.js import { useTransition } from 'react'; export default function TabButton({ children, isActive, onClick }) { @@ -202,7 +202,7 @@ export default function TabButton({ children, isActive, onClick }) { ``` -```js AboutTab.js +```js src/AboutTab.js export default function AboutTab() { return (

          Welcome to my profile!

          @@ -210,7 +210,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js +```js src/PostsTab.js import { memo } from 'react'; const PostsTab = memo(function PostsTab() { @@ -244,7 +244,7 @@ function SlowPost({ index }) { export default PostsTab; ``` -```js ContactTab.js +```js src/ContactTab.js export default function ContactTab() { return ( <> @@ -320,7 +320,7 @@ export default function TabContainer() { } ``` -```js TabButton.js +```js src/TabButton.js import { useTransition } from 'react'; export default function TabButton({ children, isActive, onClick }) { @@ -338,7 +338,7 @@ export default function TabButton({ children, isActive, onClick }) { ``` -```js AboutTab.js +```js src/AboutTab.js export default function AboutTab() { return (

          Welcome to my profile!

          @@ -346,7 +346,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js +```js src/PostsTab.js import { memo } from 'react'; const PostsTab = memo(function PostsTab() { @@ -380,7 +380,7 @@ function SlowPost({ index }) { export default PostsTab; ``` -```js ContactTab.js +```js src/ContactTab.js export default function ContactTab() { return ( <> @@ -473,7 +473,7 @@ export default function TabContainer() { } ``` -```js TabButton.js active +```js src/TabButton.js active import { useTransition } from 'react'; export default function TabButton({ children, isActive, onClick }) { @@ -493,7 +493,7 @@ export default function TabButton({ children, isActive, onClick }) { } ``` -```js AboutTab.js +```js src/AboutTab.js export default function AboutTab() { return (

          Welcome to my profile!

          @@ -501,7 +501,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js +```js src/PostsTab.js import { memo } from 'react'; const PostsTab = memo(function PostsTab() { @@ -535,7 +535,7 @@ function SlowPost({ index }) { export default PostsTab; ``` -```js ContactTab.js +```js src/ContactTab.js export default function ContactTab() { return ( <> @@ -616,7 +616,7 @@ export default function TabContainer() { } ``` -```js TabButton.js active +```js src/TabButton.js active import { useTransition } from 'react'; export default function TabButton({ children, isActive, onClick }) { @@ -639,7 +639,7 @@ export default function TabButton({ children, isActive, onClick }) { } ``` -```js AboutTab.js +```js src/AboutTab.js export default function AboutTab() { return (

          Welcome to my profile!

          @@ -647,7 +647,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js +```js src/PostsTab.js import { memo } from 'react'; const PostsTab = memo(function PostsTab() { @@ -681,7 +681,7 @@ function SlowPost({ index }) { export default PostsTab; ``` -```js ContactTab.js +```js src/ContactTab.js export default function ContactTab() { return ( <> @@ -751,7 +751,7 @@ export default function TabContainer() { } ``` -```js TabButton.js +```js src/TabButton.js export default function TabButton({ children, isActive, onClick }) { if (isActive) { return {children} @@ -766,7 +766,7 @@ export default function TabButton({ children, isActive, onClick }) { } ``` -```js AboutTab.js hidden +```js src/AboutTab.js hidden export default function AboutTab() { return (

          Welcome to my profile!

          @@ -774,7 +774,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js hidden +```js src/PostsTab.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -830,7 +830,7 @@ function use(promise) { } ``` -```js ContactTab.js hidden +```js src/ContactTab.js hidden export default function ContactTab() { return ( <> @@ -847,7 +847,7 @@ export default function ContactTab() { ``` -```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. @@ -937,7 +937,7 @@ export default function TabContainer() { } ``` -```js TabButton.js active +```js src/TabButton.js active import { useTransition } from 'react'; export default function TabButton({ children, isActive, onClick }) { @@ -960,7 +960,7 @@ export default function TabButton({ children, isActive, onClick }) { } ``` -```js AboutTab.js hidden +```js src/AboutTab.js hidden export default function AboutTab() { return (

          Welcome to my profile!

          @@ -968,7 +968,7 @@ export default function AboutTab() { } ``` -```js PostsTab.js hidden +```js src/PostsTab.js hidden import { fetchData } from './data.js'; // Note: this component is written using an experimental API @@ -1024,7 +1024,7 @@ function use(promise) { } ``` -```js ContactTab.js hidden +```js src/ContactTab.js hidden export default function ContactTab() { return ( <> @@ -1041,7 +1041,7 @@ export default function ContactTab() { ``` -```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. @@ -1138,7 +1138,7 @@ Here is a tiny simplified router example using transitions for navigations. } ``` -```js App.js +```js src/App.js import { Suspense, useState, useTransition } from 'react'; import IndexPage from './IndexPage.js'; import ArtistPage from './ArtistPage.js'; @@ -1189,7 +1189,7 @@ function BigSpinner() { } ``` -```js Layout.js +```js src/Layout.js export default function Layout({ children, isPending }) { return (
          @@ -1206,7 +1206,7 @@ export default function Layout({ children, isPending }) { } ``` -```js IndexPage.js +```js src/IndexPage.js export default function IndexPage({ navigate }) { return ( + }} + > + Add comment + ); } ``` -```js App.js hidden +```js src/App.js hidden import { AddCommentContainer } from "./AddCommentContainer.js"; export default function App() { @@ -1559,7 +1560,7 @@ export default function App() { } ``` -```js index.js hidden +```js src/index.js hidden // TODO: update to import from stable // react instead of canary once the `use` // Hook is in a stable release of React