From 5f2b3992c35ba7e43a046faacd0680c514b0e8c6 Mon Sep 17 00:00:00 2001 From: Anthony Laflamme Date: Wed, 27 Mar 2024 07:24:22 -0400 Subject: [PATCH 1/9] fix: Fix capitalization of word Component/s --- README.md | 2 +- src/components/Layout/HomeContent.js | 20 +- src/components/Seo.tsx | 2 +- .../blog/2021/06/08/the-plan-for-react-18.md | 4 +- .../blog/2021/12/17/react-conf-2021-recap.md | 2 +- .../blog/2022/03/08/react-18-upgrade-guide.md | 22 +-- src/content/blog/2022/03/29/react-v18.md | 26 +-- ...-what-we-have-been-working-on-june-2022.md | 6 +- .../blog/2023/03/16/introducing-react-dev.md | 14 +- ...what-we-have-been-working-on-march-2023.md | 24 +-- ...t-we-have-been-working-on-february-2024.md | 8 +- src/content/community/team.md | 2 +- src/content/community/versioning-policy.md | 4 +- src/content/community/videos.md | 2 +- .../learn/add-react-to-an-existing-project.md | 20 +- src/content/learn/adding-interactivity.md | 16 +- .../learn/choosing-the-state-structure.md | 16 +- src/content/learn/conditional-rendering.md | 16 +- src/content/learn/describing-the-ui.md | 38 ++-- src/content/learn/escape-hatches.md | 18 +- .../extracting-state-logic-into-a-reducer.md | 16 +- .../importing-and-exporting-components.md | 54 +++--- src/content/learn/index.md | 34 ++-- .../javascript-in-jsx-with-curly-braces.md | 2 +- src/content/learn/keeping-components-pure.md | 58 +++--- .../learn/lifecycle-of-reactive-effects.md | 60 +++--- src/content/learn/managing-state.md | 26 +-- .../learn/manipulating-the-dom-with-refs.md | 30 +-- .../learn/passing-data-deeply-with-context.md | 72 +++---- .../learn/passing-props-to-a-component.md | 46 ++--- .../learn/preserving-and-resetting-state.md | 78 ++++---- .../learn/reacting-to-input-with-state.md | 14 +- .../learn/referencing-values-with-refs.md | 26 +-- .../learn/removing-effect-dependencies.md | 28 +-- src/content/learn/render-and-commit.md | 28 +-- src/content/learn/rendering-lists.md | 30 +-- src/content/learn/responding-to-events.md | 32 ++-- .../learn/reusing-logic-with-custom-hooks.md | 64 +++---- .../scaling-up-with-reducer-and-context.md | 40 ++-- .../learn/separating-events-from-effects.md | 22 +-- .../learn/sharing-state-between-components.md | 56 +++--- .../learn/start-a-new-react-project.md | 12 +- .../learn/state-a-components-memory.md | 42 ++-- src/content/learn/state-as-a-snapshot.md | 10 +- .../learn/synchronizing-with-effects.md | 84 ++++---- src/content/learn/thinking-in-react.md | 52 ++--- src/content/learn/tutorial-tic-tac-toe.md | 116 +++++------ src/content/learn/typescript.md | 8 +- .../learn/understanding-your-ui-as-a-tree.md | 26 +-- .../learn/updating-objects-in-state.md | 4 +- src/content/learn/writing-markup-with-jsx.md | 10 +- .../learn/you-might-not-need-an-effect.md | 88 ++++----- src/content/learn/your-first-component.md | 64 +++---- .../reference/react-dom/client/createRoot.md | 28 +-- .../reference/react-dom/client/hydrateRoot.md | 20 +- .../reference/react-dom/client/index.md | 6 +- .../reference/react-dom/components/common.md | 8 +- .../reference/react-dom/components/form.md | 2 +- .../reference/react-dom/components/index.md | 16 +- .../reference/react-dom/components/input.md | 10 +- .../reference/react-dom/components/link.md | 16 +- .../reference/react-dom/components/meta.md | 12 +- .../reference/react-dom/components/option.md | 2 +- .../reference/react-dom/components/script.md | 12 +- .../reference/react-dom/components/select.md | 4 +- .../reference/react-dom/components/style.md | 10 +- .../react-dom/components/textarea.md | 6 +- .../reference/react-dom/components/title.md | 14 +- .../reference/react-dom/createPortal.md | 12 +- .../reference/react-dom/findDOMNode.md | 20 +- .../reference/react-dom/hooks/useFormState.md | 10 +- .../react-dom/hooks/useFormStatus.md | 14 +- src/content/reference/react-dom/hydrate.md | 8 +- src/content/reference/react-dom/index.md | 8 +- src/content/reference/react-dom/preconnect.md | 4 +- .../reference/react-dom/prefetchDNS.md | 4 +- src/content/reference/react-dom/preinit.md | 4 +- .../reference/react-dom/preinitModule.md | 4 +- src/content/reference/react-dom/preload.md | 4 +- .../reference/react-dom/preloadModule.md | 4 +- src/content/reference/react-dom/render.md | 16 +- .../reference/react-dom/server/index.md | 2 +- .../server/renderToPipeableStream.md | 20 +- .../server/renderToReadableStream.md | 20 +- .../react-dom/server/renderToStaticMarkup.md | 4 +- .../react-dom/server/renderToString.md | 10 +- .../react-dom/unmountComponentAtNode.md | 8 +- src/content/reference/react/Children.md | 26 +-- src/content/reference/react/Component.md | 180 +++++++++--------- src/content/reference/react/Fragment.md | 2 +- src/content/reference/react/Profiler.md | 12 +- src/content/reference/react/PureComponent.md | 22 +-- src/content/reference/react/StrictMode.md | 46 ++--- src/content/reference/react/Suspense.md | 56 +++--- src/content/reference/react/apis.md | 4 +- src/content/reference/react/cache.md | 42 ++-- src/content/reference/react/cloneElement.md | 8 +- src/content/reference/react/components.md | 8 +- src/content/reference/react/createContext.md | 24 +-- src/content/reference/react/createElement.md | 8 +- src/content/reference/react/createFactory.md | 2 +- src/content/reference/react/createRef.md | 10 +- src/content/reference/react/forwardRef.md | 42 ++-- src/content/reference/react/hooks.md | 16 +- src/content/reference/react/index.md | 10 +- src/content/reference/react/lazy.md | 18 +- src/content/reference/react/legacy.md | 2 +- src/content/reference/react/memo.md | 54 +++--- .../reference/react/startTransition.md | 2 +- src/content/reference/react/use-client.md | 60 +++--- src/content/reference/react/use-server.md | 2 +- src/content/reference/react/use.md | 26 +-- src/content/reference/react/useCallback.md | 40 ++-- src/content/reference/react/useContext.md | 42 ++-- src/content/reference/react/useDebugValue.md | 8 +- .../reference/react/useDeferredValue.md | 22 +-- src/content/reference/react/useEffect.md | 56 +++--- src/content/reference/react/useId.md | 12 +- .../reference/react/useImperativeHandle.md | 14 +- .../reference/react/useInsertionEffect.md | 10 +- .../reference/react/useLayoutEffect.md | 22 +-- src/content/reference/react/useMemo.md | 64 +++---- src/content/reference/react/useReducer.md | 20 +- src/content/reference/react/useRef.md | 30 +-- src/content/reference/react/useState.md | 34 ++-- .../reference/react/useSyncExternalStore.md | 30 +-- src/content/reference/react/useTransition.md | 30 +-- .../components-and-hooks-must-be-pure.md | 36 ++-- src/content/reference/rules/index.md | 8 +- .../rules/react-calls-components-and-hooks.md | 26 +-- src/content/reference/rules/rules-of-hooks.md | 8 +- .../warnings/invalid-hook-call-warning.md | 8 +- src/content/warnings/unknown-prop.md | 4 +- 133 files changed, 1571 insertions(+), 1571 deletions(-) diff --git a/README.md b/README.md index 966131db576..9b11287efd5 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ The documentation is divided into several sections with a different tone and pur 1. Follow the ["Running locally"](#running-locally) instructions 1. Save the files and check in the browser - 1. Changes to React components in `src` will hot-reload + 1. Changes to React Components in `src` will hot-reload 1. Changes to markdown files in `content` will hot-reload 1. If working with plugins, you may need to remove the `.cache` directory and restart the server diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index e1fab6d713a..921ded9197d 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -151,7 +151,7 @@ export function HomeContent() {
Create user interfaces from components
React lets you build user interfaces out of individual pieces - called components. Create your own React components like{' '} + called components. Create your own React Components like{' '} Thumbnail, LikeButton, and{' '} Video. Then combine them into entire screens, pages, and apps. @@ -164,7 +164,7 @@ export function HomeContent() { Whether you work on your own or with thousands of other developers, using React feels the same. It is designed to let you - seamlessly combine components written by independent people, + seamlessly combine Components written by independent people, teams, and organizations. @@ -172,9 +172,9 @@ export function HomeContent() {
-
Write components with code and markup
+
Write Components with code and markup
- React components are JavaScript functions. Want to show some + React Components are JavaScript functions. Want to show some content conditionally? Use an if statement. Displaying a list? Try array map(). Learning React is learning programming. @@ -187,7 +187,7 @@ export function HomeContent() { This markup syntax is called JSX. It is a JavaScript syntax extension popularized by React. Putting JSX markup close to - related rendering logic makes React components easy to create, + related rendering logic makes React Components easy to create, maintain, and delete.
@@ -197,7 +197,7 @@ export function HomeContent() {
Add interactivity wherever you need it
- React components receive data and return what should appear on the + React Components receive data and return what should appear on the screen. You can pass them new data in response to an interaction, like when the user types into an input. React will then update the screen to match the new data. @@ -230,7 +230,7 @@ export function HomeContent() { with a framework - React is a library. It lets you put components together, but it + React is a library. It lets you put Components together, but it doesn’t prescribe how to do routing and data fetching. To build an entire app with React, we recommend a full-stack React framework like Next.js or{' '} @@ -243,7 +243,7 @@ export function HomeContent() {
React is also an architecture. Frameworks that implement it let - you fetch data in asynchronous components that run on the server + you fetch data in asynchronous Components that run on the server or even during the build. Read data from a file or a database, and pass it down to your interactive components. @@ -378,7 +378,7 @@ export function HomeContent() { let you build apps in React for Android, iOS, and more. They look and feel native because their UIs{' '} are truly native. It’s not a web view—your - React components render real Android and iOS views + React Components render real Android and iOS views provided by the platform.

@@ -411,7 +411,7 @@ export function HomeContent() { React approaches changes with care. Every React commit is tested on business-critical surfaces with over a billion - users. Over 100,000 React components at Meta help validate + users. Over 100,000 React Components at Meta help validate every migration strategy.
diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx index dfc4f61049d..210a67603b5 100644 --- a/src/components/Seo.tsx +++ b/src/components/Seo.tsx @@ -55,7 +55,7 @@ export const Seo = withRouter( // Twitter's meta parser is not very good. const twitterTitle = pageTitle.replace(/[<>]/g, ''); let description = isHomePage - ? 'React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizations.' + ? 'React is the library for web and native user interfaces. Build user interfaces out of individual pieces called Components written in JavaScript. React is designed to let you seamlessly combine Components written by independent people, teams, and organizations.' : 'The library for web and native user interfaces'; return ( diff --git a/src/content/blog/2021/06/08/the-plan-for-react-18.md b/src/content/blog/2021/06/08/the-plan-for-react-18.md index 0bf744c1ddb..42c0d75d6a0 100644 --- a/src/content/blog/2021/06/08/the-plan-for-react-18.md +++ b/src/content/blog/2021/06/08/the-plan-for-react-18.md @@ -30,9 +30,9 @@ If you've been following our research into the future of React (we don't expect ## A gradual adoption strategy {/*a-gradual-adoption-strategy*/} -Since concurrency in React 18 is opt-in, there are no significant out-of-the-box breaking changes to component behavior. **You can upgrade to React 18 with minimal or no changes to your application code, with a level of effort comparable to a typical major React release**. Based on our experience converting several apps to React 18, we expect that many users will be able to upgrade within a single afternoon. +Since concurrency in React 18 is opt-in, there are no significant out-of-the-box breaking changes to Component behavior. **You can upgrade to React 18 with minimal or no changes to your application code, with a level of effort comparable to a typical major React release**. Based on our experience converting several apps to React 18, we expect that many users will be able to upgrade within a single afternoon. -We successfully shipped concurrent features to tens of thousands of components at Facebook, and in our experience, we've found that most React components “just work” without additional changes. We're committed to making sure this is a smooth upgrade for the entire community, so today we're announcing the React 18 Working Group. +We successfully shipped concurrent features to tens of thousands of Components at Facebook, and in our experience, we've found that most React Components “just work” without additional changes. We're committed to making sure this is a smooth upgrade for the entire community, so today we're announcing the React 18 Working Group. ## Working with the community {/*working-with-the-community*/} diff --git a/src/content/blog/2021/12/17/react-conf-2021-recap.md b/src/content/blog/2021/12/17/react-conf-2021-recap.md index 89e407af3f0..3ce1ec4c7ce 100644 --- a/src/content/blog/2021/12/17/react-conf-2021-recap.md +++ b/src/content/blog/2021/12/17/react-conf-2021-recap.md @@ -65,7 +65,7 @@ For a demo of upgrading to React 18, see [Shruti Kapoor](https://twitter.com/shr React 18 also includes improvements to server-side rendering performance using Suspense. -Streaming server rendering lets you generate HTML from React components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster. +Streaming server rendering lets you generate HTML from React Components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster. For a deep dive, see [Shaundai Person](https://twitter.com/shaundai)’s talk here: diff --git a/src/content/blog/2022/03/08/react-18-upgrade-guide.md b/src/content/blog/2022/03/08/react-18-upgrade-guide.md index 66da896ec4a..18f3cf570bd 100644 --- a/src/content/blog/2022/03/08/react-18-upgrade-guide.md +++ b/src/content/blog/2022/03/08/react-18-upgrade-guide.md @@ -119,7 +119,7 @@ For more information, see the [working group discussion here](https://github.com -**If your app doesn't work after upgrading, check whether it's wrapped in ``.** [Strict Mode has gotten stricter in React 18](#updates-to-strict-mode), and not all your components may be resilient to the new checks it adds in development mode. If removing Strict Mode fixes your app, you can remove it during the upgrade, and then add it back (either at the top or for a part of the tree) after you fix the issues that it's pointing out. +**If your app doesn't work after upgrading, check whether it's wrapped in ``.** [Strict Mode has gotten stricter in React 18](#updates-to-strict-mode), and not all your Components may be resilient to the new checks it adds in development mode. If removing Strict Mode fixes your app, you can remove it during the upgrade, and then add it back (either at the top or for a part of the tree) after you fix the issues that it's pointing out. @@ -231,13 +231,13 @@ React 18 also introduces new APIs for concurrent rendering such as `startTransit ## Updates to Strict Mode {/*updates-to-strict-mode*/} -In the future, we'd like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before. +In the future, we'd like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same Component state as before. -This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once. +This feature will give React better performance out-of-the-box, but requires Components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once. -To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount. +To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a Component mounts for the first time, restoring the previous state on the second mount. -Before this change, React would mount the component and create the effects: +Before this change, React would mount the Component and create the effects: ``` * React mounts the component. @@ -245,7 +245,7 @@ Before this change, React would mount the component and create the effects: * Effect effects are created. ``` -With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode: +With Strict Mode in React 18, React will simulate unmounting and remounting the Component in development mode: ``` * React mounts the component. @@ -254,7 +254,7 @@ With Strict Mode in React 18, React will simulate unmounting and remounting the * React simulates unmounting the component. * Layout effects are destroyed. * Effects are destroyed. -* React simulates mounting the component with the previous state. +* React simulates mounting the Component with the previous state. * Layout effect setup code runs * Effect setup code runs ``` @@ -304,18 +304,18 @@ If you need to support Internet Explorer we recommend you stay with React 17. * **Consistent useEffect timing**: React now always synchronously flushes effect functions if the update was triggered during a discrete user input event such as a click or a keydown event. Previously, the behavior wasn't always predictable or consistent. * **Stricter hydration errors**: Hydration mismatches due to missing or extra text content are now treated like errors instead of warnings. React will no longer attempt to "patch up" individual nodes by inserting or deleting a node on the client in an attempt to match the server markup, and will revert to client rendering up to the closest `` boundary in the tree. This ensures the hydrated tree is consistent and avoids potential privacy and security holes that can be caused by hydration mismatches. -* **Suspense trees are always consistent:** If a component suspends before it's fully added to the tree, React will not add it to the tree in an incomplete state or fire its effects. Instead, React will throw away the new tree completely, wait for the asynchronous operation to finish, and then retry rendering again from scratch. React will render the retry attempt concurrently, and without blocking the browser. -* **Layout Effects with Suspense**: When a tree re-suspends and reverts to a fallback, React will now clean up layout effects, and then re-create them when the content inside the boundary is shown again. This fixes an issue which prevented component libraries from correctly measuring layout when used with Suspense. +* **Suspense trees are always consistent:** If a Component suspends before it's fully added to the tree, React will not add it to the tree in an incomplete state or fire its effects. Instead, React will throw away the new tree completely, wait for the asynchronous operation to finish, and then retry rendering again from scratch. React will render the retry attempt concurrently, and without blocking the browser. +* **Layout Effects with Suspense**: When a tree re-suspends and reverts to a fallback, React will now clean up layout effects, and then re-create them when the content inside the boundary is shown again. This fixes an issue which prevented Component libraries from correctly measuring layout when used with Suspense. * **New JS Environment Requirements**: React now depends on modern browsers features including `Promise`, `Symbol`, and `Object.assign`. If you support older browsers and devices such as Internet Explorer which do not provide modern browser features natively or have non-compliant implementations, consider including a global polyfill in your bundled application. ## Other Notable Changes {/*other-notable-changes*/} ### React {/*react*/} -* **Components can now render `undefined`:** React no longer warns if you return `undefined` from a component. This makes the allowed component return values consistent with values that are allowed in the middle of a component tree. We suggest to use a linter to prevent mistakes like forgetting a `return` statement before JSX. +* **Components can now render `undefined`:** React no longer warns if you return `undefined` from a component. This makes the allowed Component return values consistent with values that are allowed in the middle of a Component tree. We suggest to use a linter to prevent mistakes like forgetting a `return` statement before JSX. * **In tests, `act` warnings are now opt-in:** If you're running end-to-end tests, the `act` warnings are unnecessary. We've introduced an [opt-in](https://github.com/reactwg/react-18/discussions/102) mechanism so you can enable them only for unit tests where they are useful and beneficial. * **No warning about `setState` on unmounted components:** Previously, React warned about memory leaks when you call `setState` on an unmounted component. This warning was added for subscriptions, but people primarily run into it in scenarios where setting state is fine, and workarounds make the code worse. We've [removed](https://github.com/facebook/react/pull/22114) this warning. -* **No suppression of console logs:** When you use Strict Mode, React renders each component twice to help you find unexpected side effects. In React 17, we've suppressed console logs for one of the two renders to make the logs easier to read. In response to [community feedback](https://github.com/facebook/react/issues/21783) about this being confusing, we've removed the suppression. Instead, if you have React DevTools installed, the second log's renders will be displayed in grey, and there will be an option (off by default) to suppress them completely. +* **No suppression of console logs:** When you use Strict Mode, React renders each Component twice to help you find unexpected side effects. In React 17, we've suppressed console logs for one of the two renders to make the logs easier to read. In response to [community feedback](https://github.com/facebook/react/issues/21783) about this being confusing, we've removed the suppression. Instead, if you have React DevTools installed, the second log's renders will be displayed in grey, and there will be an option (off by default) to suppress them completely. * **Improved memory usage:** React now cleans up more internal fields on unmount, making the impact from unfixed memory leaks that may exist in your application code less severe. ### React DOM Server {/*react-dom-server*/} diff --git a/src/content/blog/2022/03/29/react-v18.md b/src/content/blog/2022/03/29/react-v18.md index 743404c1af9..22b484960e9 100644 --- a/src/content/blog/2022/03/29/react-v18.md +++ b/src/content/blog/2022/03/29/react-v18.md @@ -48,15 +48,15 @@ A key property of Concurrent React is that rendering is interruptible. When you In a concurrent render, this is not always the case. React may start rendering an update, pause in the middle, then continue later. It may even abandon an in-progress render altogether. React guarantees that the UI will appear consistent even if a render is interrupted. To do this, it waits to perform DOM mutations until the end, once the entire tree has been evaluated. With this capability, React can prepare new screens in the background without blocking the main thread. This means the UI can respond immediately to user input even if it’s in the middle of a large rendering task, creating a fluid user experience. -Another example is reusable state. Concurrent React can remove sections of the UI from the screen, then add them back later while reusing the previous state. For example, when a user tabs away from a screen and back, React should be able to restore the previous screen in the same state it was in before. In an upcoming minor, we're planning to add a new component called `` that implements this pattern. Similarly, you’ll be able to use Offscreen to prepare new UI in the background so that it’s ready before the user reveals it. +Another example is reusable state. Concurrent React can remove sections of the UI from the screen, then add them back later while reusing the previous state. For example, when a user tabs away from a screen and back, React should be able to restore the previous screen in the same state it was in before. In an upcoming minor, we're planning to add a new Component called `` that implements this pattern. Similarly, you’ll be able to use Offscreen to prepare new UI in the background so that it’s ready before the user reveals it. Concurrent rendering is a powerful new tool in React and most of our new features are built to take advantage of it, including Suspense, transitions, and streaming server rendering. But React 18 is just the beginning of what we aim to build on this new foundation. ## Gradually Adopting Concurrent Features {/*gradually-adopting-concurrent-features*/} -Technically, concurrent rendering is a breaking change. Because concurrent rendering is interruptible, components behave slightly differently when it is enabled. +Technically, concurrent rendering is a breaking change. Because concurrent rendering is interruptible, Components behave slightly differently when it is enabled. -In our testing, we've upgraded thousands of components to React 18. What we've found is that nearly all existing components "just work" with concurrent rendering, without any changes. However, some of them may require some additional migration effort. Although the changes are usually small, you'll still have the ability to make them at your own pace. The new rendering behavior in React 18 is **only enabled in the parts of your app that use new features.** +In our testing, we've upgraded thousands of Components to React 18. What we've found is that nearly all existing Components "just work" with concurrent rendering, without any changes. However, some of them may require some additional migration effort. Although the changes are usually small, you'll still have the ability to make them at your own pace. The new rendering behavior in React 18 is **only enabled in the parts of your app that use new features.** The overall upgrade strategy is to get your application running on React 18 without breaking existing code. Then you can gradually start adding concurrent features at your own pace. You can use [``](/reference/react/StrictMode) to help surface concurrency-related bugs during development. Strict Mode doesn't affect production behavior, but during development it will log extra warnings and double-invoke functions that are expected to be idempotent. It won't catch everything, but it's effective at preventing the most common types of mistakes. @@ -148,7 +148,7 @@ Transitions will opt in to concurrent rendering, which allows the update to be i ### New Suspense Features {/*new-suspense-features*/} -Suspense lets you declaratively specify the loading state for a part of the component tree if it's not yet ready to be displayed: +Suspense lets you declaratively specify the loading state for a part of the Component tree if it's not yet ready to be displayed: ```js }> @@ -194,13 +194,13 @@ The existing `renderToString` method keeps working but is discouraged. ### New Strict Mode Behaviors {/*new-strict-mode-behaviors*/} -In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before. +In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same Component state as before. -This feature will give React apps better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once. +This feature will give React apps better performance out-of-the-box, but requires Components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once. -To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount. +To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a Component mounts for the first time, restoring the previous state on the second mount. -Before this change, React would mount the component and create the effects: +Before this change, React would mount the Component and create the effects: ``` * React mounts the component. @@ -209,7 +209,7 @@ Before this change, React would mount the component and create the effects: ``` -With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode: +With Strict Mode in React 18, React will simulate unmounting and remounting the Component in development mode: ``` * React mounts the component. @@ -218,7 +218,7 @@ With Strict Mode in React 18, React will simulate unmounting and remounting the * React simulates unmounting the component. * Layout effects are destroyed. * Effects are destroyed. -* React simulates mounting the component with the previous state. +* React simulates mounting the Component with the previous state. * Layout effects are created. * Effects are created. ``` @@ -229,7 +229,7 @@ With Strict Mode in React 18, React will simulate unmounting and remounting the #### useId {/*useid*/} -`useId` is a new Hook for generating unique IDs on both the client and server, while avoiding hydration mismatches. It is primarily useful for component libraries integrating with accessibility APIs that require unique IDs. This solves an issue that already exists in React 17 and below, but it's even more important in React 18 because of how the new streaming server renderer delivers HTML out-of-order. [See docs here](/reference/react/useId). +`useId` is a new Hook for generating unique IDs on both the client and server, while avoiding hydration mismatches. It is primarily useful for Component libraries integrating with accessibility APIs that require unique IDs. This solves an issue that already exists in React 17 and below, but it's even more important in React 18 because of how the new streaming server renderer delivers HTML out-of-order. [See docs here](/reference/react/useId). > Note > @@ -277,10 +277,10 @@ See [How to Upgrade to React 18](/blog/2022/03/08/react-18-upgrade-guide) for st * Assume Symbols are always available. ([#23348](https://github.com/facebook/react/pull/23348) by [@sebmarkbage](https://github.com/sebmarkbage)) * Remove `object-assign` polyfill. ([#23351](https://github.com/facebook/react/pull/23351) by [@sebmarkbage](https://github.com/sebmarkbage)) * Remove unsupported `unstable_changedBits` API. ([#20953](https://github.com/facebook/react/pull/20953) by [@acdlite](https://github.com/acdlite)) -* Allow components to render undefined. ([#21869](https://github.com/facebook/react/pull/21869) by [@rickhanlonii](https://github.com/rickhanlonii)) +* Allow Components to render undefined. ([#21869](https://github.com/facebook/react/pull/21869) by [@rickhanlonii](https://github.com/rickhanlonii)) * Flush `useEffect` resulting from discrete events like clicks synchronously. ([#21150](https://github.com/facebook/react/pull/21150) by [@acdlite](https://github.com/acdlite)) * Suspense `fallback={undefined}` now behaves the same as `null` and isn't ignored. ([#21854](https://github.com/facebook/react/pull/21854) by [@rickhanlonii](https://github.com/rickhanlonii)) -* Consider all `lazy()` resolving to the same component equivalent. ([#20357](https://github.com/facebook/react/pull/20357) by [@sebmarkbage](https://github.com/sebmarkbage)) +* Consider all `lazy()` resolving to the same Component equivalent. ([#20357](https://github.com/facebook/react/pull/20357) by [@sebmarkbage](https://github.com/sebmarkbage)) * Don't patch console during first render. ([#22308](https://github.com/facebook/react/pull/22308) by [@lunaruan](https://github.com/lunaruan)) * Improve memory usage. ([#21039](https://github.com/facebook/react/pull/21039) by [@bgirard](https://github.com/bgirard)) * Improve messages if string coercion throws (Temporal.*, Symbol, etc.) ([#22064](https://github.com/facebook/react/pull/22064) by [@justingrant](https://github.com/justingrant)) diff --git a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md index 5e8456ea3c5..be6d89e5729 100644 --- a/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md +++ b/src/content/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022.md @@ -49,7 +49,7 @@ We’re also working on a playground for exploring many aspects of the compiler. Today, if you want to hide and show a component, you have two options. One is to add or remove it from the tree completely. The problem with this approach is that the state of your UI is lost each time you unmount, including state stored in the DOM, like scroll position. -The other option is to keep the component mounted and toggle the appearance visually using CSS. This preserves the state of your UI, but it comes at a performance cost, because React must keep rendering the hidden component and all of its children whenever it receives new updates. +The other option is to keep the Component mounted and toggle the appearance visually using CSS. This preserves the state of your UI, but it comes at a performance cost, because React must keep rendering the hidden Component and all of its children whenever it receives new updates. Offscreen introduces a third option: hide the UI visually, but deprioritize its content. The idea is similar in spirit to the `content-visibility` CSS property: when content is hidden, it doesn't need to stay in sync with the rest of the UI. React can defer the rendering work until the rest of the app is idle, or until the content becomes visible again. @@ -62,9 +62,9 @@ Offscreen is a low level capability that unlocks high level features. Similar to ## Transition Tracing {/*transition-tracing*/} -Currently, React has two profiling tools. The [original Profiler](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) shows an overview of all the commits in a profiling session. For each commit, it also shows all components that rendered and the amount of time it took for them to render. We also have a beta version of a [Timeline Profiler](https://github.com/reactwg/react-18/discussions/76) introduced in React 18 that shows when components schedule updates and when React works on these updates. Both of these profilers help developers identify performance problems in their code. +Currently, React has two profiling tools. The [original Profiler](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) shows an overview of all the commits in a profiling session. For each commit, it also shows all Components that rendered and the amount of time it took for them to render. We also have a beta version of a [Timeline Profiler](https://github.com/reactwg/react-18/discussions/76) introduced in React 18 that shows when Components schedule updates and when React works on these updates. Both of these profilers help developers identify performance problems in their code. -We’ve realized that developers don’t find knowing about individual slow commits or components out of context that useful. It’s more useful to know about what actually causes the slow commits. And that developers want to be able to track specific interactions (eg a button click, an initial load, or a page navigation) to watch for performance regressions and to understand why an interaction was slow and how to fix it. +We’ve realized that developers don’t find knowing about individual slow commits or Components out of context that useful. It’s more useful to know about what actually causes the slow commits. And that developers want to be able to track specific interactions (eg a button click, an initial load, or a page navigation) to watch for performance regressions and to understand why an interaction was slow and how to fix it. We previously tried to solve this issue by creating an [Interaction Tracing API](https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16), but it had some fundamental design flaws that reduced the accuracy of tracking why an interaction was slow and sometimes resulted in interactions never ending. We ended up [removing this API](https://github.com/facebook/react/pull/20037) because of these issues. 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 4ce209d7195..38099448d99 100644 --- a/src/content/blog/2023/03/16/introducing-react-dev.md +++ b/src/content/blog/2023/03/16/introducing-react-dev.md @@ -16,7 +16,7 @@ Today we are thrilled to launch [react.dev](https://react.dev), the new home for ## tl;dr {/*tldr*/} -* The new React site ([react.dev](https://react.dev)) teaches modern React with function components and Hooks. +* The new React site ([react.dev](https://react.dev)) teaches modern React with function Components and Hooks. * We've included diagrams, illustrations, challenges, and over 600 new interactive examples. * The previous React documentation site has now moved to [legacy.reactjs.org](https://legacy.reactjs.org). @@ -34,7 +34,7 @@ If you haven't seen the new homepage yet, check it out! ## Going all-in on modern React with Hooks {/*going-all-in-on-modern-react-with-hooks*/} -When we released React Hooks in 2018, the Hooks docs assumed the reader is familiar with class components. This helped the community adopt Hooks very swiftly, but after a while the old docs failed to serve the new readers. New readers had to learn React twice: once with class components and then once again with Hooks. +When we released React Hooks in 2018, the Hooks docs assumed the reader is familiar with class components. This helped the community adopt Hooks very swiftly, but after a while the old docs failed to serve the new readers. New readers had to learn React twice: once with class Components and then once again with Hooks. **The new docs teach React with Hooks from the beginning.** The docs are divided in two main sections: @@ -45,7 +45,7 @@ Let's have a closer look at what you can find in each section. -There are still a few rare class component use cases that do not yet have a Hook-based equivalent. Class components remain supported, and are documented in the [Legacy API](/reference/react/legacy) section of the new site. +There are still a few rare class Component use cases that do not yet have a Hook-based equivalent. Class Components remain supported, and are documented in the [Legacy API](/reference/react/legacy) section of the new site. @@ -222,7 +222,7 @@ body { -We'd also like to highlight [Thinking in React](/learn/thinking-in-react)—that's the tutorial that made React "click" for many of us. **We've updated both of these classic tutorials to use function components and Hooks,** so they're as good as new. +We'd also like to highlight [Thinking in React](/learn/thinking-in-react)—that's the tutorial that made React "click" for many of us. **We've updated both of these classic tutorials to use function Components and Hooks,** so they're as good as new. @@ -440,7 +440,7 @@ Notice the "Show solution" button in the left bottom corner. It's handy if you w When we couldn't figure out how to explain something with code and words alone, we've added diagrams that help provide some intuition. For example, here is one of the diagrams from [Preserving and Resetting State](/learn/preserving-and-resetting-state): - + When `section` changes to `div`, the `section` is deleted and the new `div` is added @@ -457,8 +457,8 @@ We've confirmed with the browser vendors that this depiction is 100% scientifica In the [API Reference](/reference/react), every React API now has a dedicated page. This includes all kinds of APIs: - Built-in Hooks like [`useState`](/reference/react/useState). -- Built-in components like [``](/reference/react/Suspense). -- Built-in browser components like [``](/reference/react-dom/components/input). +- Built-in Components like [``](/reference/react/Suspense). +- Built-in browser Components like [``](/reference/react-dom/components/input). - Framework-oriented APIs like [`renderToPipeableStream`](/reference/react-dom/server/renderToReadableStream). - Other React APIs like [`memo`](/reference/react/memo). diff --git a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md index 1f6b911e1ed..2d8ad24b264 100644 --- a/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md +++ b/src/content/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023.md @@ -24,17 +24,17 @@ RSC combines the simple "request/response" mental model of server-centric Multi- Since our last update, we have merged the [React Server Components RFC](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md) to ratify the proposal. We resolved outstanding issues with the [React Server Module Conventions](https://github.com/reactjs/rfcs/blob/main/text/0227-server-module-conventions.md) proposal, and reached consensus with our partners to go with the `"use client"` convention. These documents also act as specification for what an RSC-compatible implementation should support. -The biggest change is that we introduced [`async` / `await`](https://github.com/reactjs/rfcs/pull/229) as the primary way to do data fetching from Server Components. We also plan to support data loading from the client by introducing a new Hook called `use` that unwraps Promises. Although we can't support `async / await` in arbitrary components in client-only apps, we plan to add support for it when you structure your client-only app similar to how RSC apps are structured. +The biggest change is that we introduced [`async` / `await`](https://github.com/reactjs/rfcs/pull/229) as the primary way to do data fetching from Server Components. We also plan to support data loading from the client by introducing a new Hook called `use` that unwraps Promises. Although we can't support `async / await` in arbitrary Components in client-only apps, we plan to add support for it when you structure your client-only app similar to how RSC apps are structured. Now that we have data fetching pretty well sorted, we're exploring the other direction: sending data from the client to the server, so that you can execute database mutations and implement forms. We're doing this by letting you pass Server Action functions across the server/client boundary, which the client can then call, providing seamless RPC. Server Actions also give you progressively enhanced forms before JavaScript loads. -React Server Components has shipped in [Next.js App Router](/learn/start-a-new-react-project#nextjs-app-router). This showcases a deep integration of a router that really buys into RSC as a primitive, but it's not the only way to build a RSC-compatible router and framework. There's a clear separation for features provided by the RSC spec and implementation. React Server Components is meant as a spec for components that work across compatible React frameworks. +React Server Components has shipped in [Next.js App Router](/learn/start-a-new-react-project#nextjs-app-router). This showcases a deep integration of a router that really buys into RSC as a primitive, but it's not the only way to build a RSC-compatible router and framework. There's a clear separation for features provided by the RSC spec and implementation. React Server Components is meant as a spec for Components that work across compatible React frameworks. We generally recommend using an existing framework, but if you need to build your own custom framework, it is possible. Building your own RSC-compatible framework is not as easy as we'd like it to be, mainly due to the deep bundler integration needed. The current generation of bundlers are great for use on the client, but they weren't designed with first-class support for splitting a single module graph between the server and the client. This is why we're now partnering directly with bundler developers to get the primitives for RSC built-in. ## Asset Loading {/*asset-loading*/} -[Suspense](/reference/react/Suspense) lets you specify what to display on the screen while the data or code for your components is still being loaded. This lets your users progressively see more content while the page is loading as well as during the router navigations that load more data and code. However, from the user's perspective, data loading and rendering do not tell the whole story when considering whether new content is ready. By default, browsers load stylesheets, fonts, and images independently, which can lead to UI jumps and consecutive layout shifts. +[Suspense](/reference/react/Suspense) lets you specify what to display on the screen while the data or code for your Components is still being loaded. This lets your users progressively see more content while the page is loading as well as during the router navigations that load more data and code. However, from the user's perspective, data loading and rendering do not tell the whole story when considering whether new content is ready. By default, browsers load stylesheets, fonts, and images independently, which can lead to UI jumps and consecutive layout shifts. We're working to fully integrate Suspense with the loading lifecycle of stylesheets, fonts, and images, so that React takes them into account to determine whether the content is ready to be displayed. Without any change to the way you author your React components, updates will behave in a more coherent and pleasing manner. As an optimization, we will also provide a manual way to preload assets like fonts directly from components. @@ -42,23 +42,23 @@ We are currently implementing these features and will have more to share soon. ## Document Metadata {/*document-metadata*/} -Different pages and screens in your app may have different metadata like the `` tag, description, and other `<meta>` tags specific to this screen. From the maintenance perspective, it's more scalable to keep this information close to the React component for that page or screen. However, the HTML tags for this metadata need to be in the document `<head>` which is typically rendered in a component at the very root of your app. +Different pages and screens in your app may have different metadata like the `<title>` tag, description, and other `<meta>` tags specific to this screen. From the maintenance perspective, it's more scalable to keep this information close to the React Component for that page or screen. However, the HTML tags for this metadata need to be in the document `<head>` which is typically rendered in a Component at the very root of your app. Today, people solve this problem with one of the two techniques. -One technique is to render a special third-party component that moves `<title>`, `<meta>`, and other tags inside it into the document `<head>`. This works for major browsers but there are many clients which do not run client-side JavaScript, such as Open Graph parsers, and so this technique is not universally suitable. +One technique is to render a special third-party Component that moves `<title>`, `<meta>`, and other tags inside it into the document `<head>`. This works for major browsers but there are many clients which do not run client-side JavaScript, such as Open Graph parsers, and so this technique is not universally suitable. Another technique is to server-render the page in two parts. First, the main content is rendered and all such tags are collected. Then, the `<head>` is rendered with these tags. Finally, the `<head>` and the main content are sent to the browser. This approach works, but it prevents you from taking advantage of the [React 18's Streaming Server Renderer](/reference/react-dom/server/renderToReadableStream) because you'd have to wait for all content to render before sending the `<head>`. -This is why we're adding built-in support for rendering `<title>`, `<meta>`, and metadata `<link>` tags anywhere in your component tree out of the box. It would work the same way in all environments, including fully client-side code, SSR, and in the future, RSC. We will share more details about this soon. +This is why we're adding built-in support for rendering `<title>`, `<meta>`, and metadata `<link>` tags anywhere in your Component tree out of the box. It would work the same way in all environments, including fully client-side code, SSR, and in the future, RSC. We will share more details about this soon. ## React Optimizing Compiler {/*react-optimizing-compiler*/} Since our previous update we've been actively iterating on the design of [React Forget](/blog/2022/06/15/react-labs-what-we-have-been-working-on-june-2022#react-compiler), an optimizing compiler for React. We've previously talked about it as an "auto-memoizing compiler", and that is true in some sense. But building the compiler has helped us understand React's programming model even more deeply. A better way to understand React Forget is as an automatic *reactivity* compiler. -The core idea of React is that developers define their UI as a function of the current state. You work with plain JavaScript values — numbers, strings, arrays, objects — and use standard JavaScript idioms — if/else, for, etc — to describe your component logic. The mental model is that React will re-render whenever the application state changes. We believe this simple mental model and keeping close to JavaScript semantics is an important principle in React's programming model. +The core idea of React is that developers define their UI as a function of the current state. You work with plain JavaScript values — numbers, strings, arrays, objects — and use standard JavaScript idioms — if/else, for, etc — to describe your Component logic. The mental model is that React will re-render whenever the application state changes. We believe this simple mental model and keeping close to JavaScript semantics is an important principle in React's programming model. -The catch is that React can sometimes be *too* reactive: it can re-render too much. For example, in JavaScript we don't have cheap ways to compare if two objects or arrays are equivalent (having the same keys and values), so creating a new object or array on each render may cause React to do more work than it strictly needs to. This means developers have to explicitly memoize components so as to not over-react to changes. +The catch is that React can sometimes be *too* reactive: it can re-render too much. For example, in JavaScript we don't have cheap ways to compare if two objects or arrays are equivalent (having the same keys and values), so creating a new object or array on each render may cause React to do more work than it strictly needs to. This means developers have to explicitly memoize Components so as to not over-react to changes. Our goal with React Forget is to ensure that React apps have just the right amount of reactivity by default: that apps re-render only when state values *meaningfully* change. From an implementation perspective this means automatically memoizing, but we believe that the reactivity framing is a better way to understand React and Forget. One way to think about this is that React currently re-renders when object identity changes. With Forget, React re-renders when the semantic value changes — but without incurring the runtime cost of deep comparisons. @@ -70,20 +70,20 @@ The core of the compiler is almost completely decoupled from Babel, and the core As we refactored the compiler over the last few months, we wanted to focus on refining the core compilation model to ensure we could handle complexities such as conditionals, loops, reassignment, and mutation. However, JavaScript has a lot of ways to express each of those features: if/else, ternaries, for, for-in, for-of, etc. Trying to support the full language up-front would have delayed the point where we could validate the core model. Instead, we started with a small but representative subset of the language: let/const, if/else, for loops, objects, arrays, primitives, function calls, and a few other features. As we gained confidence in the core model and refined our internal abstractions, we expanded the supported language subset. We're also explicit about syntax we don't yet support, logging diagnostics and skipping compilation for unsupported input. We have utilities to try the compiler on Meta's codebases and see what unsupported features are most common so we can prioritize those next. We'll continue incrementally expanding towards supporting the whole language. -Making plain JavaScript in React components reactive requires a compiler with a deep understanding of semantics so that it can understand exactly what the code is doing. By taking this approach, we're creating a system for reactivity within JavaScript that lets you write product code of any complexity with the full expressivity of the language, instead of being limited to a domain specific language. +Making plain JavaScript in React Components reactive requires a compiler with a deep understanding of semantics so that it can understand exactly what the code is doing. By taking this approach, we're creating a system for reactivity within JavaScript that lets you write product code of any complexity with the full expressivity of the language, instead of being limited to a domain specific language. ## Offscreen Rendering {/*offscreen-rendering*/} Offscreen rendering is an upcoming capability in React for rendering screens in the background without additional performance overhead. You can think of it as a version of the [`content-visibility` CSS property](https://developer.mozilla.org/en-US/docs/Web/CSS/content-visibility) that works not only for DOM elements but React components, too. During our research, we've discovered a variety of use cases: - A router can prerender screens in the background so that when a user navigates to them, they're instantly available. -- A tab switching component can preserve the state of hidden tabs, so the user can switch between them without losing their progress. -- A virtualized list component can prerender additional rows above and below the visible window. +- A tab switching Component can preserve the state of hidden tabs, so the user can switch between them without losing their progress. +- A virtualized list Component can prerender additional rows above and below the visible window. - When opening a modal or popup, the rest of the app can be put into "background" mode so that events and updates are disabled for everything except the modal. Most React developers will not interact with React's offscreen APIs directly. Instead, offscreen rendering will be integrated into things like routers and UI libraries, and then developers who use those libraries will automatically benefit without additional work. -The idea is that you should be able to render any React tree offscreen without changing the way you write your components. When a component is rendered offscreen, it does not actually *mount* until the component becomes visible — its effects are not fired. For example, if a component uses `useEffect` to log analytics when it appears for the first time, prerendering won't mess up the accuracy of those analytics. Similarly, when a component goes offscreen, its effects are unmounted, too. A key feature of offscreen rendering is that you can toggle the visibility of a component without losing its state. +The idea is that you should be able to render any React tree offscreen without changing the way you write your components. When a Component is rendered offscreen, it does not actually *mount* until the Component becomes visible — its effects are not fired. For example, if a Component uses `useEffect` to log analytics when it appears for the first time, prerendering won't mess up the accuracy of those analytics. Similarly, when a Component goes offscreen, its effects are unmounted, too. A key feature of offscreen rendering is that you can toggle the visibility of a Component without losing its state. Since our last update, we've tested an experimental version of prerendering internally at Meta in our React Native apps on Android and iOS, with positive performance results. We've also improved how offscreen rendering works with Suspense — suspending inside an offscreen tree will not trigger Suspense fallbacks. Our remaining work involves finalizing the primitives that are exposed to library developers. We expect to publish an RFC later this year, alongside an experimental API for testing and feedback. diff --git a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md index 03fc85c37fd..183b6ff1159 100644 --- a/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md +++ b/src/content/blog/2024/02/15/react-labs-what-we-have-been-working-on-february-2024.md @@ -30,7 +30,7 @@ As discussed in our [previous post](/blog/2023/03/22/react-labs-what-we-have-bee Manual memoization is a reasonable compromise, but we weren’t satisfied. Our vision is for React to *automatically* re-render just the right parts of the UI when state changes, *without compromising on React’s core mental model*. We believe that React’s approach — UI as a simple function of state, with standard JavaScript values and idioms — is a key part of why React has been approachable for so many developers. That’s why we’ve invested in building an optimizing compiler for React. -JavaScript is a notoriously challenging language to optimize, thanks to its loose rules and dynamic nature. React Compiler is able to compile code safely by modeling both the rules of JavaScript *and* the “rules of React”. For example, React components must be idempotent — returning the same value given the same inputs — and can’t mutate props or state values. These rules limit what developers can do and help to carve out a safe space for the compiler to optimize. +JavaScript is a notoriously challenging language to optimize, thanks to its loose rules and dynamic nature. React Compiler is able to compile code safely by modeling both the rules of JavaScript *and* the “rules of React”. For example, React Components must be idempotent — returning the same value given the same inputs — and can’t mutate props or state values. These rules limit what developers can do and help to carve out a safe space for the compiler to optimize. Of course, we understand that developers sometimes bend the rules a bit, and our goal is to make React Compiler work out of the box on as much code as possible. The compiler attempts to detect when code doesn’t strictly follow React’s rules and will either compile the code where safe or skip compilation if it isn’t safe. We’re testing against Meta’s large and varied codebase in order to help validate this approach. @@ -58,7 +58,7 @@ By default, Actions are submitted within a [transition](/reference/react/useTran Alongside Actions, we're introducing a feature named [`useOptimistic`](/reference/react/useOptimistic) for managing optimistic state updates. With this hook, you can apply temporary updates that are automatically reverted once the final state commits. For Actions, this allows you to optimistically set the final state of the data on the client, assuming the submission is successful, and revert to the value for data received from the server. It works using regular `async`/`await`, so it works the same whether you're using `fetch` on the client, or a Server Action from the server. -Library authors can implement custom `action={fn}` props in their own components with `useTransition`. Our intent is for libraries to adopt the Actions pattern when designing their component APIs, to provide a consistent experience for React developers. For example, if your library provides a `<Calendar onSelect={eventHandler}>` component, consider also exposing a `<Calendar selectAction={action}>` API, too. +Library authors can implement custom `action={fn}` props in their own Components with `useTransition`. Our intent is for libraries to adopt the Actions pattern when designing their Component APIs, to provide a consistent experience for React developers. For example, if your library provides a `<Calendar onSelect={eventHandler}>` component, consider also exposing a `<Calendar selectAction={action}>` API, too. While we initially focused on Server Actions for client-server data transfer, our philosophy for React is to provide the same programming model across all platforms and environments. When possible, if we introduce a feature on the client, we aim to make it also work on the server, and vice versa. This philosophy allows us to create a single set of APIs that work no matter where your app runs, making it easier to upgrade to different environments later. @@ -72,9 +72,9 @@ Canaries are a change to the way we develop React. Previously, features would be React Server Components, Asset Loading, Document Metadata, and Actions have all landed in the React Canary, and we've added docs for these features on react.dev: -- **Directives**: [`"use client"`](/reference/react/use-client) and [`"use server"`](/reference/react/use-server) are bundler features designed for full-stack React frameworks. They mark the "split points" between the two environments: `"use client"` instructs the bundler to generate a `<script>` tag (like [Astro Islands](https://docs.astro.build/en/concepts/islands/#creating-an-island)), while `"use server"` tells the bundler to generate a POST endpoint (like [tRPC Mutations](https://trpc.io/docs/concepts)). Together, they let you write reusable components that compose client-side interactivity with the related server-side logic. +- **Directives**: [`"use client"`](/reference/react/use-client) and [`"use server"`](/reference/react/use-server) are bundler features designed for full-stack React frameworks. They mark the "split points" between the two environments: `"use client"` instructs the bundler to generate a `<script>` tag (like [Astro Islands](https://docs.astro.build/en/concepts/islands/#creating-an-island)), while `"use server"` tells the bundler to generate a POST endpoint (like [tRPC Mutations](https://trpc.io/docs/concepts)). Together, they let you write reusable Components that compose client-side interactivity with the related server-side logic. -- **Document Metadata**: we added built-in support for rendering [`<title>`](/reference/react-dom/components/title), [`<meta>`](/reference/react-dom/components/meta), and metadata [`<link>`](/reference/react-dom/components/link) tags anywhere in your component tree. These work the same way in all environments, including fully client-side code, SSR, and RSC. This provides built-in support for features pioneered by libraries like [React Helmet](https://github.com/nfl/react-helmet). +- **Document Metadata**: we added built-in support for rendering [`<title>`](/reference/react-dom/components/title), [`<meta>`](/reference/react-dom/components/meta), and metadata [`<link>`](/reference/react-dom/components/link) tags anywhere in your Component tree. These work the same way in all environments, including fully client-side code, SSR, and RSC. This provides built-in support for features pioneered by libraries like [React Helmet](https://github.com/nfl/react-helmet). - **Asset Loading**: we integrated Suspense with the loading lifecycle of resources such as stylesheets, fonts, and scripts so that React takes them into account to determine whether the content in elements like [`<style>`](/reference/react-dom/components/style), [`<link>`](/reference/react-dom/components/link), and [`<script>`](/reference/react-dom/components/script) are ready to be displayed. We’ve also added new [Resource Loading APIs](/reference/react-dom#resource-preloading-apis) like `preload` and `preinit` to provide greater control for when a resource should load and initialize. diff --git a/src/content/community/team.md b/src/content/community/team.md index bb28fe886cc..f23cec3b109 100644 --- a/src/content/community/team.md +++ b/src/content/community/team.md @@ -10,7 +10,7 @@ React development is led by a dedicated team working full time at Meta. It also ## React Core {/*react-core*/} -The React Core team members work full time on the core component APIs, the engine that powers React DOM and React Native, React DevTools, and the React documentation website. +The React Core team members work full time on the core Component APIs, the engine that powers React DOM and React Native, React DevTools, and the React documentation website. Current members of the React team are listed in alphabetical order below. diff --git a/src/content/community/versioning-policy.md b/src/content/community/versioning-policy.md index fad926c5768..68673e7651f 100644 --- a/src/content/community/versioning-policy.md +++ b/src/content/community/versioning-policy.md @@ -32,11 +32,11 @@ Instead, we release new features in minor versions. That means that minor releas As we change React over time, we try to minimize the effort required to take advantage of new features. When possible, we'll keep an older API working, even if that means putting it in a separate package. For example, [mixins have been discouraged for years](https://legacy.reactjs.org/blog/2016/07/13/mixins-considered-harmful.html) but they're supported to this day [via create-react-class](https://legacy.reactjs.org/docs/react-without-es6.html#mixins) and many codebases continue to use them in stable, legacy code. -Over a million developers use React, collectively maintaining millions of components. The Facebook codebase alone has over 50,000 React components. That means we need to make it as easy as possible to upgrade to new versions of React; if we make large changes without a migration path, people will be stuck on old versions. We test these upgrade paths on Facebook itself – if our team of less than 10 people can update 50,000+ components alone, we hope the upgrade will be manageable for anyone using React. In many cases, we write [automated scripts](https://github.com/reactjs/react-codemod) to upgrade component syntax, which we then include in the open-source release for everyone to use. +Over a million developers use React, collectively maintaining millions of components. The Facebook codebase alone has over 50,000 React components. That means we need to make it as easy as possible to upgrade to new versions of React; if we make large changes without a migration path, people will be stuck on old versions. We test these upgrade paths on Facebook itself – if our team of less than 10 people can update 50,000+ Components alone, we hope the upgrade will be manageable for anyone using React. In many cases, we write [automated scripts](https://github.com/reactjs/react-codemod) to upgrade Component syntax, which we then include in the open-source release for everyone to use. ### Gradual upgrades via warnings {/*gradual-upgrades-via-warnings*/} -Development builds of React include many helpful warnings. Whenever possible, we add warnings in preparation for future breaking changes. That way, if your app has no warnings on the latest release, it will be compatible with the next major release. This allows you to upgrade your apps one component at a time. +Development builds of React include many helpful warnings. Whenever possible, we add warnings in preparation for future breaking changes. That way, if your app has no warnings on the latest release, it will be compatible with the next major release. This allows you to upgrade your apps one Component at a time. Development warnings won't affect the runtime behavior of your app. That way, you can feel confident that your app will behave the same way between the development and production builds -- the only differences are that the production build won't log the warnings and that it is more efficient. (If you ever notice otherwise, please file an issue.) diff --git a/src/content/community/videos.md b/src/content/community/videos.md index 3fad95786e6..9d827878b4d 100644 --- a/src/content/community/videos.md +++ b/src/content/community/videos.md @@ -28,7 +28,7 @@ For a demo of upgrading to React 18, see [Shruti Kapoor](https://twitter.com/shr React 18 also includes improvements to server-side rendering performance using Suspense. -Streaming server rendering lets you generate HTML from React components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster. +Streaming server rendering lets you generate HTML from React Components on the server, and stream that HTML to your users. In React 18, you can use `Suspense` to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster. For a deep dive, see [Shaundai Person](https://twitter.com/shaundai)’s talk here: 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 f494b0ab1e9..3bb6462487e 100644 --- a/src/content/learn/add-react-to-an-existing-project.md +++ b/src/content/learn/add-react-to-an-existing-project.md @@ -4,7 +4,7 @@ title: Add React to an Existing Project <Intro> -If you want to add some interactivity to your existing project, you don't have to rewrite it in React. Add React to your existing stack, and render interactive React components anywhere. +If you want to add some interactivity to your existing project, you don't have to rewrite it in React. Add React to your existing stack, and render interactive React Components anywhere. </Intro> @@ -30,7 +30,7 @@ Many React-based frameworks are full-stack and let your React app take advantage ## Using React for a part of your existing page {/*using-react-for-a-part-of-your-existing-page*/} -Let's say you have an existing page built with another technology (either a server one like Rails, or a client one like Backbone), and you want to render interactive React components somewhere on that page. That's a common way to integrate React--in fact, it's how most React usage looked at Meta for many years! +Let's say you have an existing page built with another technology (either a server one like Rails, or a client one like Backbone), and you want to render interactive React Components somewhere on that page. That's a common way to integrate React--in fact, it's how most React usage looked at Meta for many years! You can do this in two steps: @@ -41,7 +41,7 @@ The exact approach depends on your existing page setup, so let's walk through so ### Step 1: Set up a modular JavaScript environment {/*step-1-set-up-a-modular-javascript-environment*/} -A modular JavaScript environment lets you write your React components in individual files, as opposed to writing all of your code in a single file. It also lets you use all the wonderful packages published by other developers on the [npm](https://www.npmjs.com/) registry--including React itself! How you do this depends on your existing setup: +A modular JavaScript environment lets you write your React Components in individual files, as opposed to writing all of your code in a single file. It also lets you use all the wonderful packages published by other developers on the [npm](https://www.npmjs.com/) registry--including React itself! How you do this depends on your existing setup: * **If your app is already split into files that use `import` statements,** try to use the setup you already have. Check whether writing `<div />` in your JS code causes a syntax error. If it causes a syntax error, you might need to [transform your JavaScript code with Babel](https://babeljs.io/setup), and enable the [Babel React preset](https://babeljs.io/docs/babel-preset-react) to use JSX. @@ -73,7 +73,7 @@ import { createRoot } from 'react-dom/client'; // Clear the existing HTML content document.body.innerHTML = '<div id="app"></div>'; -// Render your React component instead +// Render your React Component instead const root = createRoot(document.getElementById('app')); root.render(<h1>Hello, world</h1>); ``` @@ -88,7 +88,7 @@ Integrating a modular JavaScript environment into an existing project for the fi </Note> -### Step 2: Render React components anywhere on the page {/*step-2-render-react-components-anywhere-on-the-page*/} +### Step 2: Render React Components anywhere on the page {/*step-2-render-react-components-anywhere-on-the-page*/} In the previous step, you put this code at the top of your main file: @@ -98,7 +98,7 @@ import { createRoot } from 'react-dom/client'; // Clear the existing HTML content document.body.innerHTML = '<div id="app"></div>'; -// Render your React component instead +// Render your React Component instead const root = createRoot(document.getElementById('app')); root.render(<h1>Hello, world</h1>); ``` @@ -107,7 +107,7 @@ Of course, you don't actually want to clear the existing HTML content! Delete this code. -Instead, you probably want to render your React components in specific places in your HTML. Open your HTML page (or the server templates that generate it) and add a unique [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) attribute to any tag, for example: +Instead, you probably want to render your React Components in specific places in your HTML. Open your HTML page (or the server templates that generate it) and add a unique [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) attribute to any tag, for example: ```html <!-- ... somewhere in your html ... --> @@ -115,7 +115,7 @@ Instead, you probably want to render your React components in specific places in <!-- ... more html ... --> ``` -This lets you find that HTML element with [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) and pass it to [`createRoot`](/reference/react-dom/client/createRoot) so that you can render your own React component inside: +This lets you find that HTML element with [`document.getElementById`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById) and pass it to [`createRoot`](/reference/react-dom/client/createRoot) so that you can render your own React Component inside: <Sandpack> @@ -146,9 +146,9 @@ root.render(<NavigationBar />); </Sandpack> -Notice how the original HTML content from `index.html` is preserved, but your own `NavigationBar` React component now appears inside the `<nav id="navigation">` from your HTML. Read the [`createRoot` usage documentation](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) to learn more about rendering React components inside an existing HTML page. +Notice how the original HTML content from `index.html` is preserved, but your own `NavigationBar` React Component now appears inside the `<nav id="navigation">` from your HTML. Read the [`createRoot` usage documentation](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) to learn more about rendering React Components inside an existing HTML page. -When you adopt React in an existing project, it's common to start with small interactive components (like buttons), and then gradually keep "moving upwards" until eventually your entire page is built with React. If you ever reach that point, we recommend migrating to [a React framework](/learn/start-a-new-react-project) right after to get the most out of React. +When you adopt React in an existing project, it's common to start with small interactive Components (like buttons), and then gradually keep "moving upwards" until eventually your entire page is built with React. If you ever reach that point, we recommend migrating to [a React framework](/learn/start-a-new-react-project) right after to get the most out of React. ## Using React Native in an existing native mobile app {/*using-react-native-in-an-existing-native-mobile-app*/} diff --git a/src/content/learn/adding-interactivity.md b/src/content/learn/adding-interactivity.md index 0d4a3b23fce..2149df0f5ec 100644 --- a/src/content/learn/adding-interactivity.md +++ b/src/content/learn/adding-interactivity.md @@ -4,14 +4,14 @@ title: Adding Interactivity <Intro> -Some things on the screen update in response to user input. For example, clicking an image gallery switches the active image. In React, data that changes over time is called *state.* You can add state to any component, and update it as needed. In this chapter, you'll learn how to write components that handle interactions, update their state, and display different output over time. +Some things on the screen update in response to user input. For example, clicking an image gallery switches the active image. In React, data that changes over time is called *state.* You can add state to any component, and update it as needed. In this chapter, you'll learn how to write Components that handle interactions, update their state, and display different output over time. </Intro> <YouWillLearn isChapter={true}> * [How to handle user-initiated events](/learn/responding-to-events) -* [How to make components "remember" information with state](/learn/state-a-components-memory) +* [How to make Components "remember" information with state](/learn/state-a-components-memory) * [How React updates the UI in two phases](/learn/render-and-commit) * [Why state doesn't update right after you change it](/learn/state-as-a-snapshot) * [How to queue multiple state updates](/learn/queueing-a-series-of-state-updates) @@ -24,7 +24,7 @@ Some things on the screen update in response to user input. For example, clickin React lets you add *event handlers* to your JSX. Event handlers are your own functions that will be triggered in response to user interactions like clicking, hovering, focusing on form inputs, and so on. -Built-in components like `<button>` only support built-in browser events like `onClick`. However, you can also create your own components, and give their event handler props any application-specific names that you like. +Built-in Components like `<button>` only support built-in browser events like `onClick`. However, you can also create your own components, and give their event handler props any application-specific names that you like. <Sandpack> @@ -76,7 +76,7 @@ Read **[Responding to Events](/learn/responding-to-events)** to learn how to add Components often need to change what's on the screen as a result of an interaction. Typing into the form should update the input field, clicking "next" on an image carousel should change which image is displayed, clicking "buy" puts a product in the shopping cart. Components need to "remember" things: the current input value, the current image, the shopping cart. In React, this kind of component-specific memory is called *state.* -You can add state to a component with a [`useState`](/reference/react/useState) Hook. *Hooks* are special functions that let your components use React features (state is one of those features). The `useState` Hook lets you declare a state variable. It takes the initial state and returns a pair of values: the current state, and a state setter function that lets you update it. +You can add state to a Component with a [`useState`](/reference/react/useState) Hook. *Hooks* are special functions that let your Components use React features (state is one of those features). The `useState` Hook lets you declare a state variable. It takes the initial state and returns a pair of values: the current state, and a state setter function that lets you update it. ```js const [index, setIndex] = useState(0); @@ -235,12 +235,12 @@ Read **[State: A Component's Memory](/learn/state-a-components-memory)** to lear ## Render and commit {/*render-and-commit*/} -Before your components are displayed on the screen, they must be rendered by React. Understanding the steps in this process will help you think about how your code executes and explain its behavior. +Before your Components are displayed on the screen, they must be rendered by React. Understanding the steps in this process will help you think about how your code executes and explain its behavior. -Imagine that your components are cooks in the kitchen, assembling tasty dishes from ingredients. In this scenario, React is the waiter who puts in requests from customers and brings them their orders. This process of requesting and serving UI has three steps: +Imagine that your Components are cooks in the kitchen, assembling tasty dishes from ingredients. In this scenario, React is the waiter who puts in requests from customers and brings them their orders. This process of requesting and serving UI has three steps: 1. **Triggering** a render (delivering the diner's order to the kitchen) -2. **Rendering** the component (preparing the order in the kitchen) +2. **Rendering** the Component (preparing the order in the kitchen) 3. **Committing** to the DOM (placing the order on the table) <IllustrationBlock sequential> @@ -320,7 +320,7 @@ Read **[State as a Snapshot](/learn/state-as-a-snapshot)** to learn why state ap ## Queueing a series of state updates {/*queueing-a-series-of-state-updates*/} -This component is buggy: clicking "+3" increments the score only once. +This Component is buggy: clicking "+3" increments the score only once. <Sandpack> diff --git a/src/content/learn/choosing-the-state-structure.md b/src/content/learn/choosing-the-state-structure.md index 5be2b4d346a..acd95a9d100 100644 --- a/src/content/learn/choosing-the-state-structure.md +++ b/src/content/learn/choosing-the-state-structure.md @@ -4,7 +4,7 @@ title: Choosing the State Structure <Intro> -Structuring state well can make a difference between a component that is pleasant to modify and debug, and one that is a constant source of bugs. Here are some tips you should consider when structuring state. +Structuring state well can make a difference between a Component that is pleasant to modify and debug, and one that is a constant source of bugs. Here are some tips you should consider when structuring state. </Intro> @@ -18,7 +18,7 @@ Structuring state well can make a difference between a component that is pleasan ## Principles for structuring state {/*principles-for-structuring-state*/} -When you write a component that holds some state, you'll have to make choices about how many state variables to use and what the shape of their data should be. While it's possible to write correct programs even with a suboptimal state structure, there are a few principles that can guide you to make better choices: +When you write a Component that holds some state, you'll have to make choices about how many state variables to use and what the shape of their data should be. While it's possible to write correct programs even with a suboptimal state structure, there are a few principles that can guide you to make better choices: 1. **Group related state.** If you always update two or more state variables at the same time, consider merging them into a single state variable. 2. **Avoid contradictions in state.** When the state is structured in a way that several pieces of state may contradict and "disagree" with each other, you leave room for mistakes. Try to avoid this. @@ -157,7 +157,7 @@ function sendMessage(text) { </Sandpack> -While this code works, it leaves the door open for "impossible" states. For example, if you forget to call `setIsSent` and `setIsSending` together, you may end up in a situation where both `isSending` and `isSent` are `true` at the same time. The more complex your component is, the harder it is to understand what happened. +While this code works, it leaves the door open for "impossible" states. For example, if you forget to call `setIsSent` and `setIsSending` together, you may end up in a situation where both `isSending` and `isSent` are `true` at the same time. The more complex your Component is, the harder it is to understand what happened. **Since `isSending` and `isSent` should never be `true` at the same time, it is better to replace them with one `status` state variable that may take one of *three* valid states:** `'typing'` (initial), `'sending'`, and `'sent'`: @@ -353,7 +353,7 @@ function Message({ messageColor }) { const [color, setColor] = useState(messageColor); ``` -Here, a `color` state variable is initialized to the `messageColor` prop. The problem is that **if the parent component passes a different value of `messageColor` later (for example, `'red'` instead of `'blue'`), the `color` *state variable* would not be updated!** The state is only initialized during the first render. +Here, a `color` state variable is initialized to the `messageColor` prop. The problem is that **if the parent Component passes a different value of `messageColor` later (for example, `'red'` instead of `'blue'`), the `color` *state variable* would not be updated!** The state is only initialized during the first render. This is why "mirroring" some prop in a state variable can lead to confusion. Instead, use the `messageColor` prop directly in your code. If you want to give it a shorter name, use a constant: @@ -377,7 +377,7 @@ function Message({ initialColor }) { ## Avoid duplication in state {/*avoid-duplication-in-state*/} -This menu list component lets you choose a single travel snack out of several: +This menu list Component lets you choose a single travel snack out of several: <Sandpack> @@ -1833,9 +1833,9 @@ Sometimes, you can also reduce state nesting by moving some of the nested state <Challenges> -#### Fix a component that's not updating {/*fix-a-component-thats-not-updating*/} +#### Fix a Component that's not updating {/*fix-a-component-thats-not-updating*/} -This `Clock` component receives two props: `color` and `time`. When you select a different color in the select box, the `Clock` component receives a different `color` prop from its parent component. However, for some reason, the displayed color doesn't update. Why? Fix the problem. +This `Clock` Component receives two props: `color` and `time`. When you select a different color in the select box, the `Clock` Component receives a different `color` prop from its parent component. However, for some reason, the displayed color doesn't update. Why? Fix the problem. <Sandpack> @@ -1890,7 +1890,7 @@ export default function App() { <Solution> -The issue is that this component has `color` state initialized with the initial value of the `color` prop. But when the `color` prop changes, this does not affect the state variable! So they get out of sync. To fix this issue, remove the state variable altogether, and use the `color` prop directly. +The issue is that this Component has `color` state initialized with the initial value of the `color` prop. But when the `color` prop changes, this does not affect the state variable! So they get out of sync. To fix this issue, remove the state variable altogether, and use the `color` prop directly. <Sandpack> diff --git a/src/content/learn/conditional-rendering.md b/src/content/learn/conditional-rendering.md index 895d610d339..1f2326b3108 100644 --- a/src/content/learn/conditional-rendering.md +++ b/src/content/learn/conditional-rendering.md @@ -4,7 +4,7 @@ title: Conditional Rendering <Intro> -Your components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators. +Your Components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators. </Intro> @@ -18,7 +18,7 @@ Your components will often need to display different things depending on differe ## Conditionally returning JSX {/*conditionally-returning-jsx*/} -Let’s say you have a `PackingList` component rendering several `Item`s, which can be marked as packed or not: +Let’s say you have a `PackingList` Component rendering several `Item`s, which can be marked as packed or not: <Sandpack> @@ -52,7 +52,7 @@ export default function PackingList() { </Sandpack> -Notice that some of the `Item` components have their `isPacked` prop set to `true` instead of `false`. You want to add a checkmark (✔) to packed items if `isPacked={true}`. +Notice that some of the `Item` Components have their `isPacked` prop set to `true` instead of `false`. You want to add a checkmark (✔) to packed items if `isPacked={true}`. You can write this as an [`if`/`else` statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/if...else) like so: @@ -106,7 +106,7 @@ Notice how you're creating branching logic with JavaScript's `if` and `return` s ### Conditionally returning nothing with `null` {/*conditionally-returning-nothing-with-null*/} -In some situations, you won't want to render anything at all. For example, say you don't want to show packed items at all. A component must return something. In this case, you can return `null`: +In some situations, you won't want to render anything at all. For example, say you don't want to show packed items at all. A Component must return something. In this case, you can return `null`: ```js if (isPacked) { @@ -115,7 +115,7 @@ if (isPacked) { return <li className="item">{name}</li>; ``` -If `isPacked` is true, the component will return nothing, `null`. Otherwise, it will return JSX to render. +If `isPacked` is true, the Component will return nothing, `null`. Otherwise, it will return JSX to render. <Sandpack> @@ -152,7 +152,7 @@ export default function PackingList() { </Sandpack> -In practice, returning `null` from a component isn't common because it might surprise a developer trying to render it. More often, you would conditionally include or exclude the component in the parent component's JSX. Here's how to do that! +In practice, returning `null` from a Component isn't common because it might surprise a developer trying to render it. More often, you would conditionally include or exclude the Component in the parent component's JSX. Here's how to do that! ## Conditionally including JSX {/*conditionally-including-jsx*/} @@ -256,7 +256,7 @@ export default function PackingList() { </Sandpack> -This style works well for simple conditions, but use it in moderation. If your components get messy with too much nested conditional markup, consider extracting child components to clean things up. In React, markup is a part of your code, so you can use tools like variables and functions to tidy up complex expressions. +This style works well for simple conditions, but use it in moderation. If your Components get messy with too much nested conditional markup, consider extracting child Components to clean things up. In React, markup is a part of your code, so you can use tools like variables and functions to tidy up complex expressions. ### Logical AND operator (`&&`) {/*logical-and-operator-*/} @@ -632,7 +632,7 @@ In this solution, two separate conditions are used to insert a space between the #### Refactor a series of `? :` to `if` and variables {/*refactor-a-series-of---to-if-and-variables*/} -This `Drink` component uses a series of `? :` conditions to show different information depending on whether the `name` prop is `"tea"` or `"coffee"`. The problem is that the information about each drink is spread across multiple conditions. Refactor this code to use a single `if` statement instead of three `? :` conditions. +This `Drink` Component uses a series of `? :` conditions to show different information depending on whether the `name` prop is `"tea"` or `"coffee"`. The problem is that the information about each drink is spread across multiple conditions. Refactor this code to use a single `if` statement instead of three `? :` conditions. <Sandpack> diff --git a/src/content/learn/describing-the-ui.md b/src/content/learn/describing-the-ui.md index ce49b85c8fe..aade376ec9a 100644 --- a/src/content/learn/describing-the-ui.md +++ b/src/content/learn/describing-the-ui.md @@ -14,17 +14,17 @@ React is a JavaScript library for rendering user interfaces (UI). UI is built fr * [When and how to create multi-component files](/learn/importing-and-exporting-components) * [How to add markup to JavaScript with JSX](/learn/writing-markup-with-jsx) * [How to use curly braces with JSX to access JavaScript functionality from your components](/learn/javascript-in-jsx-with-curly-braces) -* [How to configure components with props](/learn/passing-props-to-a-component) +* [How to configure Components with props](/learn/passing-props-to-a-component) * [How to conditionally render components](/learn/conditional-rendering) -* [How to render multiple components at a time](/learn/rendering-lists) -* [How to avoid confusing bugs by keeping components pure](/learn/keeping-components-pure) +* [How to render multiple Components at a time](/learn/rendering-lists) +* [How to avoid confusing bugs by keeping Components pure](/learn/keeping-components-pure) * [Why understanding your UI as trees is useful](/learn/understanding-your-ui-as-a-tree) </YouWillLearn> -## Your first component {/*your-first-component*/} +## Your first Component {/*your-first-component*/} -React applications are built from isolated pieces of UI called *components*. A React component is a JavaScript function that you can sprinkle with markup. Components can be as small as a button, or as large as an entire page. Here is a `Gallery` component rendering three `Profile` components: +React applications are built from isolated pieces of UI called *components*. A React Component is a JavaScript function that you can sprinkle with markup. Components can be as small as a button, or as large as an entire page. Here is a `Gallery` Component rendering three `Profile` components: <Sandpack> @@ -62,9 +62,9 @@ Read **[Your First Component](/learn/your-first-component)** to learn how to dec </LearnMore> -## Importing and exporting components {/*importing-and-exporting-components*/} +## Importing and exporting Components {/*importing-and-exporting-components*/} -You can declare many components in one file, but large files can get difficult to navigate. To solve this, you can *export* a component into its own file, and then *import* that component from another file: +You can declare many Components in one file, but large files can get difficult to navigate. To solve this, you can *export* a Component into its own file, and then *import* that Component from another file: <Sandpack> @@ -113,13 +113,13 @@ img { margin: 0 10px 10px 0; } <LearnMore path="/learn/importing-and-exporting-components"> -Read **[Importing and Exporting Components](/learn/importing-and-exporting-components)** to learn how to split components into their own files. +Read **[Importing and Exporting Components](/learn/importing-and-exporting-components)** to learn how to split Components into their own files. </LearnMore> ## Writing markup with JSX {/*writing-markup-with-jsx*/} -Each React component is a JavaScript function that may contain some markup that React renders into the browser. React components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information. +Each React Component is a JavaScript function that may contain some markup that React renders into the browser. React Components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information. If we paste existing HTML markup into a React component, it won't always work: @@ -234,9 +234,9 @@ Read **[JavaScript in JSX with Curly Braces](/learn/javascript-in-jsx-with-curly </LearnMore> -## Passing props to a component {/*passing-props-to-a-component*/} +## Passing props to a Component {/*passing-props-to-a-component*/} -React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, functions, and even JSX! +React Components use *props* to communicate with each other. Every parent Component can pass some information to its child Components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, functions, and even JSX! <Sandpack> @@ -317,7 +317,7 @@ Read **[Passing Props to a Component](/learn/passing-props-to-a-component)** to ## Conditional rendering {/*conditional-rendering*/} -Your components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators. +Your Components will often need to display different things depending on different conditions. In React, you can conditionally render JSX using JavaScript syntax like `if` statements, `&&`, and `? :` operators. In this example, the JavaScript `&&` operator is used to conditionally render a checkmark: @@ -365,7 +365,7 @@ Read **[Conditional Rendering](/learn/conditional-rendering)** to learn the diff ## Rendering lists {/*rendering-lists*/} -You will often want to display multiple similar components from a collection of data. You can use JavaScript's `filter()` and `map()` with React to filter and transform your array of data into an array of components. +You will often want to display multiple similar Components from a collection of data. You can use JavaScript's `filter()` and `map()` with React to filter and transform your array of data into an array of components. For each array item, you will need to specify a `key`. Usually, you will want to use an ID from the database as a `key`. Keys let React keep track of each item's place in the list even if the list changes. @@ -463,14 +463,14 @@ Read **[Rendering Lists](/learn/rendering-lists)** to learn how to render a list </LearnMore> -## Keeping components pure {/*keeping-components-pure*/} +## Keeping Components pure {/*keeping-components-pure*/} Some JavaScript functions are *pure.* A pure function: * **Minds its own business.** It does not change any objects or variables that existed before it was called. * **Same inputs, same output.** Given the same inputs, a pure function should always return the same result. -By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. Here is an example of an impure component: +By strictly only writing your Components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. Here is an example of an impure component: <Sandpack> @@ -496,7 +496,7 @@ export default function TeaSet() { </Sandpack> -You can make this component pure by passing a prop instead of modifying a preexisting variable: +You can make this Component pure by passing a prop instead of modifying a preexisting variable: <Sandpack> @@ -520,13 +520,13 @@ export default function TeaSet() { <LearnMore path="/learn/keeping-components-pure"> -Read **[Keeping Components Pure](/learn/keeping-components-pure)** to learn how to write components as pure, predictable functions. +Read **[Keeping Components Pure](/learn/keeping-components-pure)** to learn how to write Components as pure, predictable functions. </LearnMore> ## Your UI as a tree {/*your-ui-as-a-tree*/} -React uses trees to model the relationships between components and modules. +React uses trees to model the relationships between Components and modules. A React render tree is a representation of the parent and child relationship between components. @@ -536,7 +536,7 @@ An example React render tree. </Diagram> -Components near the top of the tree, near the root component, are considered top-level components. Components with no child components are leaf components. This categorization of components is useful for understanding data flow and rendering performance. +Components near the top of the tree, near the root component, are considered top-level components. Components with no child Components are leaf components. This categorization of Components is useful for understanding data flow and rendering performance. Modelling the relationship between JavaScript modules is another useful way to understand your app. We refer to it as a module dependency tree. diff --git a/src/content/learn/escape-hatches.md b/src/content/learn/escape-hatches.md index 23f11f54e28..f0c92c3204c 100644 --- a/src/content/learn/escape-hatches.md +++ b/src/content/learn/escape-hatches.md @@ -4,7 +4,7 @@ title: Escape Hatches <Intro> -Some of your components may need to control and synchronize with systems outside of React. For example, you might need to focus an input using the browser API, play and pause a video player implemented without React, or connect and listen to messages from a remote server. In this chapter, you'll learn the escape hatches that let you "step outside" React and connect to external systems. Most of your application logic and data flow should not rely on these features. +Some of your Components may need to control and synchronize with systems outside of React. For example, you might need to focus an input using the browser API, play and pause a video player implemented without React, or connect and listen to messages from a remote server. In this chapter, you'll learn the escape hatches that let you "step outside" React and connect to external systems. Most of your application logic and data flow should not rely on these features. </Intro> @@ -12,7 +12,7 @@ Some of your components may need to control and synchronize with systems outside * [How to "remember" information without re-rendering](/learn/referencing-values-with-refs) * [How to access DOM elements managed by React](/learn/manipulating-the-dom-with-refs) -* [How to synchronize components with external systems](/learn/synchronizing-with-effects) +* [How to synchronize Components with external systems](/learn/synchronizing-with-effects) * [How to remove unnecessary Effects from your components](/learn/you-might-not-need-an-effect) * [How an Effect's lifecycle is different from a component's](/learn/lifecycle-of-reactive-effects) * [How to prevent some values from re-triggering Effects](/learn/separating-events-from-effects) @@ -23,7 +23,7 @@ Some of your components may need to control and synchronize with systems outside ## Referencing values with refs {/*referencing-values-with-refs*/} -When you want a component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*: +When you want a Component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*: ```js const ref = useRef(0); @@ -54,7 +54,7 @@ export default function Counter() { </Sandpack> -A ref is like a secret pocket of your component that React doesn't track. For example, you can use refs to store [timeout IDs](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Element), and other objects that don't impact the component's rendering output. +A ref is like a secret pocket of your Component that React doesn't track. For example, you can use refs to store [timeout IDs](https://developer.mozilla.org/en-US/docs/Web/API/setTimeout#return_value), [DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Element), and other objects that don't impact the component's rendering output. <LearnMore path="/learn/referencing-values-with-refs"> @@ -64,7 +64,7 @@ Read **[Referencing Values with Refs](/learn/referencing-values-with-refs)** to ## Manipulating the DOM with refs {/*manipulating-the-dom-with-refs*/} -React automatically updates the DOM to match your render output, so your components won't often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. For example, clicking the button will focus the input using a ref: +React automatically updates the DOM to match your render output, so your Components won't often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. For example, clicking the button will focus the input using a ref: <Sandpack> @@ -99,7 +99,7 @@ Read **[Manipulating the DOM with Refs](/learn/manipulating-the-dom-with-refs)** ## Synchronizing with Effects {/*synchronizing-with-effects*/} -Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen. Unlike event handlers, which let you handle particular events, *Effects* let you run some code after rendering. Use them to synchronize your component with a system outside of React. +Some Components need to synchronize with external systems. For example, you might want to control a non-React Component based on the React state, set up a server connection, or send an analytics log when a Component appears on the screen. Unlike event handlers, which let you handle particular events, *Effects* let you run some code after rendering. Use them to synchronize your Component with a system outside of React. Press Play/Pause a few times and see how the video player stays synchronized to the `isPlaying` prop value: @@ -145,7 +145,7 @@ video { width: 250px; } </Sandpack> -Many Effects also "clean up" after themselves. For example, an Effect that sets up a connection to a chat server should return a *cleanup function* that tells React how to disconnect your component from that server: +Many Effects also "clean up" after themselves. For example, an Effect that sets up a connection to a chat server should return a *cleanup function* that tells React how to disconnect your Component from that server: <Sandpack> @@ -187,13 +187,13 @@ In development, React will immediately run and clean up your Effect one extra ti <LearnMore path="/learn/synchronizing-with-effects"> -Read **[Synchronizing with Effects](/learn/synchronizing-with-effects)** to learn how to synchronize components with external systems. +Read **[Synchronizing with Effects](/learn/synchronizing-with-effects)** to learn how to synchronize Components with external systems. </LearnMore> ## You Might Not Need An Effect {/*you-might-not-need-an-effect*/} -Effects are an escape hatch from the React paradigm. They let you "step outside" of React and synchronize your components with some external system. If there is no external system involved (for example, if you want to update a component's state when some props or state change), you shouldn't need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone. +Effects are an escape hatch from the React paradigm. They let you "step outside" of React and synchronize your Components with some external system. If there is no external system involved (for example, if you want to update a component's state when some props or state change), you shouldn't need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone. There are two common cases in which you don't need Effects: - **You don't need Effects to transform data for rendering.** 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 5c08c012390..56f9c732d64 100644 --- a/src/content/learn/extracting-state-logic-into-a-reducer.md +++ b/src/content/learn/extracting-state-logic-into-a-reducer.md @@ -4,7 +4,7 @@ title: Extracting State Logic into a Reducer <Intro> -Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your component in a single function, called a _reducer._ +Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your Component in a single function, called a _reducer._ </Intro> @@ -19,7 +19,7 @@ Components with many state updates spread across many event handlers can get ove ## Consolidate state logic with a reducer {/*consolidate-state-logic-with-a-reducer*/} -As your components grow in complexity, it can get harder to see at a glance all the different ways in which a component's state gets updated. For example, the `TaskApp` component below holds an array of `tasks` in state and uses three different event handlers to add, remove, and edit tasks: +As your Components grow in complexity, it can get harder to see at a glance all the different ways in which a component's state gets updated. For example, the `TaskApp` Component below holds an array of `tasks` in state and uses three different event handlers to add, remove, and edit tasks: <Sandpack> @@ -179,7 +179,7 @@ li { </Sandpack> -Each of its event handlers calls `setTasks` in order to update the state. As this component grows, so does the amount of state logic sprinkled throughout it. To reduce this complexity and keep all your logic in one easy-to-access place, you can move that state logic into a single function outside your component, **called a "reducer".** +Each of its event handlers calls `setTasks` in order to update the state. As this Component grows, so does the amount of state logic sprinkled throughout it. To reduce this complexity and keep all your logic in one easy-to-access place, you can move that state logic into a single function outside your component, **called a "reducer".** Reducers are a different way to handle state. You can migrate from `useState` to `useReducer` in three steps: @@ -457,7 +457,7 @@ You probably won't need to do this yourself, but this is similar to what React d </DeepDive> -### Step 3: Use the reducer from your component {/*step-3-use-the-reducer-from-your-component*/} +### Step 3: Use the reducer from your Component {/*step-3-use-the-reducer-from-your-component*/} Finally, you need to hook up the `tasksReducer` to your component. Import the `useReducer` Hook from React: @@ -489,7 +489,7 @@ And it returns: 1. A stateful value 2. A dispatch function (to "dispatch" user actions to the reducer) -Now it's fully wired up! Here, the reducer is declared at the bottom of the component file: +Now it's fully wired up! Here, the reducer is declared at the bottom of the Component file: <Sandpack> @@ -871,7 +871,7 @@ Reducers are not without downsides! Here's a few ways you can compare them: - **Code size:** Generally, with `useState` you have to write less code upfront. With `useReducer`, you have to write both a reducer function _and_ dispatch actions. However, `useReducer` can help cut down on the code if many event handlers modify state in a similar way. - **Readability:** `useState` is very easy to read when the state updates are simple. When they get more complex, they can bloat your component's code and make it difficult to scan. In this case, `useReducer` lets you cleanly separate the _how_ of update logic from the _what happened_ of event handlers. - **Debugging:** When you have a bug with `useState`, it can be difficult to tell _where_ the state was set incorrectly, and _why_. With `useReducer`, you can add a console log into your reducer to see every state update, and _why_ it happened (due to which `action`). If each `action` is correct, you'll know that the mistake is in the reducer logic itself. However, you have to step through more code than with `useState`. -- **Testing:** A reducer is a pure function that doesn't depend on your component. This means that you can export and test it separately in isolation. While generally it's best to test components in a more realistic environment, for complex state update logic it can be useful to assert that your reducer returns a particular state for a particular initial state and action. +- **Testing:** A reducer is a pure function that doesn't depend on your component. This means that you can export and test it separately in isolation. While generally it's best to test Components in a more realistic environment, for complex state update logic it can be useful to assert that your reducer returns a particular state for a particular initial state and action. - **Personal preference:** Some people like reducers, others don't. That's okay. It's a matter of preference. You can always convert between `useState` and `useReducer` back and forth: they are equivalent! We recommend using a reducer if you often encounter bugs due to incorrect state updates in some component, and want to introduce more structure to its code. You don't have to use reducers for everything: feel free to mix and match! You can even `useState` and `useReducer` in the same component. @@ -1107,7 +1107,7 @@ Replace these two `// TODO`s with the code to `dispatch` the corresponding actio <Hint> -The `dispatch` function is already available in both of these components because it was passed as a prop. So you need to call `dispatch` with the corresponding action object. +The `dispatch` function is already available in both of these Components because it was passed as a prop. So you need to call `dispatch` with the corresponding action object. To check the action object shape, you can look at the reducer and see which `action` fields it expects to see. For example, the `changed_selection` case in the reducer looks like this: @@ -2071,7 +2071,7 @@ case 'edited_message': { } ``` -You would also update the `Messenger` component to read the message for the currently selected contact: +You would also update the `Messenger` Component to read the message for the currently selected contact: ```js const message = state.messages[state.selectedId]; diff --git a/src/content/learn/importing-and-exporting-components.md b/src/content/learn/importing-and-exporting-components.md index b458ef402a1..7bd5314184f 100644 --- a/src/content/learn/importing-and-exporting-components.md +++ b/src/content/learn/importing-and-exporting-components.md @@ -4,23 +4,23 @@ title: Importing and Exporting Components <Intro> -The magic of components lies in their reusability: you can create components that are composed of other components. But as you nest more and more components, it often makes sense to start splitting them into different files. This lets you keep your files easy to scan and reuse components in more places. +The magic of Components lies in their reusability: you can create Components that are composed of other components. But as you nest more and more components, it often makes sense to start splitting them into different files. This lets you keep your files easy to scan and reuse Components in more places. </Intro> <YouWillLearn> -* What a root component file is +* What a root Component file is * How to import and export a component * When to use default and named imports and exports -* How to import and export multiple components from one file -* How to split components into multiple files +* How to import and export multiple Components from one file +* How to split Components into multiple files </YouWillLearn> -## The root component file {/*the-root-component-file*/} +## The root Component file {/*the-root-component-file*/} -In [Your First Component](/learn/your-first-component), you made a `Profile` component and a `Gallery` component that renders it: +In [Your First Component](/learn/your-first-component), you made a `Profile` Component and a `Gallery` Component that renders it: <Sandpack> @@ -52,15 +52,15 @@ img { margin: 0 10px 10px 0; height: 90px; } </Sandpack> -These currently live in a **root component file,** named `App.js` in this example. Depending on your setup, your root component could be in another file, though. If you use a framework with file-based routing, such as Next.js, your root component will be different for every page. +These currently live in a **root Component file,** named `App.js` in this example. Depending on your setup, your root Component could be in another file, though. If you use a framework with file-based routing, such as Next.js, your root Component will be different for every page. -## Exporting and importing a component {/*exporting-and-importing-a-component*/} +## Exporting and importing a Component {/*exporting-and-importing-a-component*/} -What if you want to change the landing screen in the future and put a list of science books there? Or place all the profiles somewhere else? It makes sense to move `Gallery` and `Profile` out of the root component file. This will make them more modular and reusable in other files. You can move a component in three steps: +What if you want to change the landing screen in the future and put a list of science books there? Or place all the profiles somewhere else? It makes sense to move `Gallery` and `Profile` out of the root Component file. This will make them more modular and reusable in other files. You can move a Component in three steps: -1. **Make** a new JS file to put the components in. -2. **Export** your function component from that file (using either [default](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/export#using_the_default_export) or [named](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/export#using_named_exports) exports). -3. **Import** it in the file where you’ll use the component (using the corresponding technique for importing [default](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import#importing_defaults) or [named](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import#import_a_single_export_from_a_module) exports). +1. **Make** a new JS file to put the Components in. +2. **Export** your function Component from that file (using either [default](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/export#using_the_default_export) or [named](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/export#using_named_exports) exports). +3. **Import** it in the file where you’ll use the Component (using the corresponding technique for importing [default](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import#importing_defaults) or [named](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import#import_a_single_export_from_a_module) exports). Here both `Profile` and `Gallery` have been moved out of `App.js` into a new file called `Gallery.js`. Now you can change `App.js` to import `Gallery` from `Gallery.js`: @@ -104,14 +104,14 @@ img { margin: 0 10px 10px 0; height: 90px; } </Sandpack> -Notice how this example is broken down into two component files now: +Notice how this example is broken down into two Component files now: 1. `Gallery.js`: - - Defines the `Profile` component which is only used within the same file and is not exported. - - Exports the `Gallery` component as a **default export.** + - Defines the `Profile` Component which is only used within the same file and is not exported. + - Exports the `Gallery` Component as a **default export.** 2. `App.js`: - Imports `Gallery` as a **default import** from `Gallery.js`. - - Exports the root `App` component as a **default export.** + - Exports the root `App` Component as a **default export.** <Note> @@ -134,7 +134,7 @@ There are two primary ways to export values with JavaScript: default exports and ![Default and named exports](/images/docs/illustrations/i_import-export.svg) -How you export your component dictates how you must import it. You will get an error if you try to import a default export the same way you would a named export! This chart can help you keep track: +How you export your Component dictates how you must import it. You will get an error if you try to import a default export the same way you would a named export! This chart can help you keep track: | Syntax | Export statement | Import statement | | ----------- | ----------- | ----------- | @@ -143,11 +143,11 @@ How you export your component dictates how you must import it. You will get an e When you write a _default_ import, you can put any name you want after `import`. For example, you could write `import Banana from './Button.js'` instead and it would still provide you with the same default export. In contrast, with named imports, the name has to match on both sides. That's why they are called _named_ imports! -**People often use default exports if the file exports only one component, and use named exports if it exports multiple components and values.** Regardless of which coding style you prefer, always give meaningful names to your component functions and the files that contain them. Components without names, like `export default () => {}`, are discouraged because they make debugging harder. +**People often use default exports if the file exports only one component, and use named exports if it exports multiple Components and values.** Regardless of which coding style you prefer, always give meaningful names to your Component functions and the files that contain them. Components without names, like `export default () => {}`, are discouraged because they make debugging harder. </DeepDive> -## Exporting and importing multiple components from the same file {/*exporting-and-importing-multiple-components-from-the-same-file*/} +## Exporting and importing multiple Components from the same file {/*exporting-and-importing-multiple-components-from-the-same-file*/} What if you want to show just one `Profile` instead of a gallery? You can export the `Profile` component, too. But `Gallery.js` already has a *default* export, and you can't have _two_ default exports. You could create a new file with a default export, or you could add a *named* export for `Profile`. **A file can only have one default export, but it can have numerous named exports!** @@ -225,21 +225,21 @@ img { margin: 0 10px 10px 0; height: 90px; } Now you're using a mix of default and named exports: * `Gallery.js`: - - Exports the `Profile` component as a **named export called `Profile`.** - - Exports the `Gallery` component as a **default export.** + - Exports the `Profile` Component as a **named export called `Profile`.** + - Exports the `Gallery` Component as a **default export.** * `App.js`: - Imports `Profile` as a **named import called `Profile`** from `Gallery.js`. - Imports `Gallery` as a **default import** from `Gallery.js`. - - Exports the root `App` component as a **default export.** + - Exports the root `App` Component as a **default export.** <Recap> On this page you learned: -* What a root component file is +* What a root Component file is * How to import and export a component * When and how to use default and named imports and exports -* How to export multiple components from the same file +* How to export multiple Components from the same file </Recap> @@ -247,11 +247,11 @@ On this page you learned: <Challenges> -#### Split the components further {/*split-the-components-further*/} +#### Split the Components further {/*split-the-components-further*/} Currently, `Gallery.js` exports both `Profile` and `Gallery`, which is a bit confusing. -Move the `Profile` component to its own `Profile.js`, and then change the `App` component to render both `<Profile />` and `<Gallery />` one after another. +Move the `Profile` Component to its own `Profile.js`, and then change the `App` Component to render both `<Profile />` and `<Gallery />` one after another. You may use either a default or a named export for `Profile`, but make sure that you use the corresponding import syntax in both `App.js` and `Gallery.js`! You can refer to the table from the deep dive above: @@ -262,7 +262,7 @@ You may use either a default or a named export for `Profile`, but make sure that <Hint> -Don't forget to import your components where they are called. Doesn't `Gallery` use `Profile`, too? +Don't forget to import your Components where they are called. Doesn't `Gallery` use `Profile`, too? </Hint> diff --git a/src/content/learn/index.md b/src/content/learn/index.md index b57655bc426..4e344a8eee7 100644 --- a/src/content/learn/index.md +++ b/src/content/learn/index.md @@ -19,11 +19,11 @@ Welcome to the React documentation! This page will give you an introduction to t </YouWillLearn> -## Creating and nesting components {/*components*/} +## Creating and nesting Components {/*components*/} -React apps are made out of *components*. A component is a piece of the UI (user interface) that has its own logic and appearance. A component can be as small as a button, or as large as an entire page. +React apps are made out of *components*. A Component is a piece of the UI (user interface) that has its own logic and appearance. A Component can be as small as a button, or as large as an entire page. -React components are JavaScript functions that return markup: +React Components are JavaScript functions that return markup: ```js function MyButton() { @@ -46,7 +46,7 @@ export default function MyApp() { } ``` -Notice that `<MyButton />` starts with a capital letter. That's how you know it's a React component. React component names must always start with a capital letter, while HTML tags must be lowercase. +Notice that `<MyButton />` starts with a capital letter. That's how you know it's a React component. React Component names must always start with a capital letter, while HTML tags must be lowercase. Have a look at the result: @@ -73,13 +73,13 @@ export default function MyApp() { </Sandpack> -The `export default` keywords specify the main component in the file. If you're not familiar with some piece of JavaScript syntax, [MDN](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) and [javascript.info](https://javascript.info/import-export) have great references. +The `export default` keywords specify the main Component in the file. If you're not familiar with some piece of JavaScript syntax, [MDN](https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export) and [javascript.info](https://javascript.info/import-export) have great references. ## Writing markup with JSX {/*writing-markup-with-jsx*/} The markup syntax you've seen above is called *JSX*. It is optional, but most React projects use JSX for its convenience. All of the [tools we recommend for local development](/learn/installation) support JSX out of the box. -JSX is stricter than HTML. You have to close tags like `<br />`. Your component also can't return multiple JSX tags. You have to wrap them into a shared parent, like a `<div>...</div>` or an empty `<>...</>` wrapper: +JSX is stricter than HTML. You have to close tags like `<br />`. Your Component also can't return multiple JSX tags. You have to wrap them into a shared parent, like a `<div>...</div>` or an empty `<>...</>` wrapper: ```js {3,6} function AboutPage() { @@ -300,7 +300,7 @@ Notice how `onClick={handleClick}` has no parentheses at the end! Do not _call_ ## Updating the screen {/*updating-the-screen*/} -Often, you'll want your component to "remember" some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add *state* to your component. +Often, you'll want your Component to "remember" some information and display it. For example, maybe you want to count the number of times a button is clicked. To do this, add *state* to your component. First, import [`useState`](/reference/react/useState) from React: @@ -336,9 +336,9 @@ function MyButton() { } ``` -React will call your component function again. This time, `count` will be `1`. Then it will be `2`. And so on. +React will call your Component function again. This time, `count` will be `1`. Then it will be `2`. And so on. -If you render the same component multiple times, each will get its own state. Click each button separately: +If you render the same Component multiple times, each will get its own state. Click each button separately: <Sandpack> @@ -385,21 +385,21 @@ Notice how each button "remembers" its own `count` state and doesn't affect othe Functions starting with `use` are called *Hooks*. `useState` is a built-in Hook provided by React. You can find other built-in Hooks in the [API reference.](/reference/react) You can also write your own Hooks by combining the existing ones. -Hooks are more restrictive than other functions. You can only call Hooks *at the top* of your components (or other Hooks). If you want to use `useState` in a condition or a loop, extract a new component and put it there. +Hooks are more restrictive than other functions. You can only call Hooks *at the top* of your Components (or other Hooks). If you want to use `useState` in a condition or a loop, extract a new Component and put it there. -## Sharing data between components {/*sharing-data-between-components*/} +## Sharing data between Components {/*sharing-data-between-components*/} In the previous example, each `MyButton` had its own independent `count`, and when each button was clicked, only the `count` for the button clicked changed: <DiagramGroup> -<Diagram name="sharing_data_child" height={367} width={407} alt="Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. Both MyButton components contain a count with value zero."> +<Diagram name="sharing_data_child" height={367} width={407} alt="Diagram showing a tree of three components, one parent labeled MyApp and two children labeled MyButton. Both MyButton Components contain a count with value zero."> Initially, each `MyButton`'s `count` state is `0` </Diagram> -<Diagram name="sharing_data_child_clicked" height={367} width={407} alt="The same diagram as the previous, with the count of the first child MyButton component highlighted indicating a click with the count value incremented to one. The second MyButton component still contains value zero." > +<Diagram name="sharing_data_child_clicked" height={367} width={407} alt="The same diagram as the previous, with the count of the first child MyButton Component highlighted indicating a click with the count value incremented to one. The second MyButton Component still contains value zero." > The first `MyButton` updates its `count` to `1` @@ -407,9 +407,9 @@ The first `MyButton` updates its `count` to `1` </DiagramGroup> -However, often you'll need components to *share data and always update together*. +However, often you'll need Components to *share data and always update together*. -To make both `MyButton` components display the same `count` and update together, you need to move the state from the individual buttons "upwards" to the closest component containing all of them. +To make both `MyButton` Components display the same `count` and update together, you need to move the state from the individual buttons "upwards" to the closest Component containing all of them. In this example, it is `MyApp`: @@ -421,7 +421,7 @@ Initially, `MyApp`'s `count` state is `0` and is passed down to both children </Diagram> -<Diagram name="sharing_data_parent_clicked" height={385} width={410} alt="The same diagram as the previous, with the count of the parent MyApp component highlighted indicating a click with the value incremented to one. The flow to both of the children MyButton components is also highlighted, and the count value in each child is set to one indicating the value was passed down." > +<Diagram name="sharing_data_parent_clicked" height={385} width={410} alt="The same diagram as the previous, with the count of the parent MyApp Component highlighted indicating a click with the value incremented to one. The flow to both of the children MyButton Components is also highlighted, and the count value in each child is set to one indicating the value was passed down." > On click, `MyApp` updates its `count` state to `1` and passes it down to both children @@ -476,7 +476,7 @@ export default function MyApp() { } ``` -The information you pass down like this is called _props_. Now the `MyApp` component contains the `count` state and the `handleClick` event handler, and *passes both of them down as props* to each of the buttons. +The information you pass down like this is called _props_. Now the `MyApp` Component contains the `count` state and the `handleClick` event handler, and *passes both of them down as props* to each of the buttons. Finally, change `MyButton` to *read* the props you have passed from its parent component: diff --git a/src/content/learn/javascript-in-jsx-with-curly-braces.md b/src/content/learn/javascript-in-jsx-with-curly-braces.md index 736065b03f0..b9f4e0ebff7 100644 --- a/src/content/learn/javascript-in-jsx-with-curly-braces.md +++ b/src/content/learn/javascript-in-jsx-with-curly-braces.md @@ -223,7 +223,7 @@ const person = { }; ``` -The component can use these values from `person` like so: +The Component can use these values from `person` like so: ```js <div style={person.theme}> diff --git a/src/content/learn/keeping-components-pure.md b/src/content/learn/keeping-components-pure.md index 6d4f55763fa..6188ae79211 100644 --- a/src/content/learn/keeping-components-pure.md +++ b/src/content/learn/keeping-components-pure.md @@ -4,14 +4,14 @@ title: Keeping Components Pure <Intro> -Some JavaScript functions are *pure.* Pure functions only perform a calculation and nothing more. By strictly only writing your components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. To get these benefits, though, there are a few rules you must follow. +Some JavaScript functions are *pure.* Pure functions only perform a calculation and nothing more. By strictly only writing your Components as pure functions, you can avoid an entire class of baffling bugs and unpredictable behavior as your codebase grows. To get these benefits, though, there are a few rules you must follow. </Intro> <YouWillLearn> * What purity is and how it helps you avoid bugs -* How to keep components pure by keeping changes out of the render phase +* How to keep Components pure by keeping changes out of the render phase * How to use Strict Mode to find mistakes in your components </YouWillLearn> @@ -45,7 +45,7 @@ function double(number) { In the above example, `double` is a **pure function.** If you pass it `3`, it will return `6`. Always. -React is designed around this concept. **React assumes that every component you write is a pure function.** This means that React components you write must always return the same JSX given the same inputs: +React is designed around this concept. **React assumes that every Component you write is a pure function.** This means that React Components you write must always return the same JSX given the same inputs: <Sandpack> @@ -81,7 +81,7 @@ If you pass `drinkers={4}`, it will return JSX containing `4 cups of water`. Alw Just like a math formula. -You could think of your components as recipes: if you follow them and don't introduce new ingredients during the cooking process, you will get the same dish every time. That "dish" is the JSX that the component serves to React to [render.](/learn/render-and-commit) +You could think of your Components as recipes: if you follow them and don't introduce new ingredients during the cooking process, you will get the same dish every time. That "dish" is the JSX that the Component serves to React to [render.](/learn/render-and-commit) <Illustration src="/images/docs/illustrations/i_puritea-recipe.png" alt="A tea recipe for x people: take x cups of water, add x spoons of tea and 0.5x spoons of spices, and 0.5x cups of milk" /> @@ -89,7 +89,7 @@ You could think of your components as recipes: if you follow them and don't intr React's rendering process must always be pure. Components should only *return* their JSX, and not *change* any objects or variables that existed before rendering—that would make them impure! -Here is a component that breaks this rule: +Here is a Component that breaks this rule: <Sandpack> @@ -115,11 +115,11 @@ export default function TeaSet() { </Sandpack> -This component is reading and writing a `guest` variable declared outside of it. This means that **calling this component multiple times will produce different JSX!** And what's more, if _other_ components read `guest`, they will produce different JSX, too, depending on when they were rendered! That's not predictable. +This Component is reading and writing a `guest` variable declared outside of it. This means that **calling this Component multiple times will produce different JSX!** And what's more, if _other_ Components read `guest`, they will produce different JSX, too, depending on when they were rendered! That's not predictable. Going back to our formula <Math><MathI>y</MathI> = 2<MathI>x</MathI></Math>, now even if <Math><MathI>x</MathI> = 2</Math>, we cannot trust that <Math><MathI>y</MathI> = 4</Math>. Our tests could fail, our users would be baffled, planes would fall out of the sky—you can see how this would lead to confusing bugs! -You can fix this component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component): +You can fix this Component by [passing `guest` as a prop instead](/learn/passing-props-to-a-component): <Sandpack> @@ -141,9 +141,9 @@ export default function TeaSet() { </Sandpack> -Now your component is pure, as the JSX it returns only depends on the `guest` prop. +Now your Component is pure, as the JSX it returns only depends on the `guest` prop. -In general, you should not expect your components to be rendered in any particular order. It doesn't matter if you call <Math><MathI>y</MathI> = 2<MathI>x</MathI></Math> before or after <Math><MathI>y</MathI> = 5<MathI>x</MathI></Math>: both formulas will resolve independently of each other. In the same way, each component should only "think for itself", and not attempt to coordinate with or depend upon others during rendering. Rendering is like a school exam: each component should calculate JSX on their own! +In general, you should not expect your Components to be rendered in any particular order. It doesn't matter if you call <Math><MathI>y</MathI> = 2<MathI>x</MathI></Math> before or after <Math><MathI>y</MathI> = 5<MathI>x</MathI></Math>: both formulas will resolve independently of each other. In the same way, each Component should only "think for itself", and not attempt to coordinate with or depend upon others during rendering. Rendering is like a school exam: each Component should calculate JSX on their own! <DeepDive> @@ -151,19 +151,19 @@ In general, you should not expect your components to be rendered in any particul Although you might not have used them all yet, in React there are three kinds of inputs that you can read while rendering: [props](/learn/passing-props-to-a-component), [state](/learn/state-a-components-memory), and [context.](/learn/passing-data-deeply-with-context) You should always treat these inputs as read-only. -When you want to *change* something in response to user input, you should [set state](/learn/state-a-components-memory) instead of writing to a variable. You should never change preexisting variables or objects while your component is rendering. +When you want to *change* something in response to user input, you should [set state](/learn/state-a-components-memory) instead of writing to a variable. You should never change preexisting variables or objects while your Component is rendering. -React offers a "Strict Mode" in which it calls each component's function twice during development. **By calling the component functions twice, Strict Mode helps find components that break these rules.** +React offers a "Strict Mode" in which it calls each component's function twice during development. **By calling the Component functions twice, Strict Mode helps find Components that break these rules.** Notice how the original example displayed "Guest #2", "Guest #4", and "Guest #6" instead of "Guest #1", "Guest #2", and "Guest #3". The original function was impure, so calling it twice broke it. But the fixed pure version works even if the function is called twice every time. **Pure functions only calculate, so calling them twice won't change anything**--just like calling `double(2)` twice doesn't change what's returned, and solving <Math><MathI>y</MathI> = 2<MathI>x</MathI></Math> twice doesn't change what <MathI>y</MathI> is. Same inputs, same outputs. Always. -Strict Mode has no effect in production, so it won't slow down the app for your users. To opt into Strict Mode, you can wrap your root component into `<React.StrictMode>`. Some frameworks do this by default. +Strict Mode has no effect in production, so it won't slow down the app for your users. To opt into Strict Mode, you can wrap your root Component into `<React.StrictMode>`. Some frameworks do this by default. </DeepDive> ### Local mutation: Your component's little secret {/*local-mutation-your-components-little-secret*/} -In the above example, the problem was that the component changed a *preexisting* variable while rendering. This is often called a **"mutation"** to make it sound a bit scarier. Pure functions don't mutate variables outside of the function's scope or objects that were created before the call—that makes them impure! +In the above example, the problem was that the Component changed a *preexisting* variable while rendering. This is often called a **"mutation"** to make it sound a bit scarier. Pure functions don't mutate variables outside of the function's scope or objects that were created before the call—that makes them impure! However, **it's completely fine to change variables and objects that you've *just* created while rendering.** In this example, you create an `[]` array, assign it to a `cups` variable, and then `push` a dozen cups into it: @@ -205,21 +205,21 @@ When possible, try to express your logic with rendering alone. You'll be surpris Writing pure functions takes some habit and discipline. But it also unlocks marvelous opportunities: -* Your components could run in a different environment—for example, on the server! Since they return the same result for the same inputs, one component can serve many user requests. -* You can improve performance by [skipping rendering](/reference/react/memo) components whose inputs have not changed. This is safe because pure functions always return the same results, so they are safe to cache. -* If some data changes in the middle of rendering a deep component tree, React can restart rendering without wasting time to finish the outdated render. Purity makes it safe to stop calculating at any time. +* Your Components could run in a different environment—for example, on the server! Since they return the same result for the same inputs, one Component can serve many user requests. +* You can improve performance by [skipping rendering](/reference/react/memo) Components whose inputs have not changed. This is safe because pure functions always return the same results, so they are safe to cache. +* If some data changes in the middle of rendering a deep Component tree, React can restart rendering without wasting time to finish the outdated render. Purity makes it safe to stop calculating at any time. -Every new React feature we're building takes advantage of purity. From data fetching to animations to performance, keeping components pure unlocks the power of the React paradigm. +Every new React feature we're building takes advantage of purity. From data fetching to animations to performance, keeping Components pure unlocks the power of the React paradigm. </DeepDive> <Recap> -* A component must be pure, meaning: +* A Component must be pure, meaning: * **It minds its own business.** It should not change any objects or variables that existed before rendering. - * **Same inputs, same output.** Given the same inputs, a component should always return the same JSX. -* Rendering can happen at any time, so components should not depend on each others' rendering sequence. -* You should not mutate any of the inputs that your components use for rendering. That includes props, state, and context. To update the screen, ["set" state](/learn/state-a-components-memory) instead of mutating preexisting objects. + * **Same inputs, same output.** Given the same inputs, a Component should always return the same JSX. +* Rendering can happen at any time, so Components should not depend on each others' rendering sequence. +* You should not mutate any of the inputs that your Components use for rendering. That includes props, state, and context. To update the screen, ["set" state](/learn/state-a-components-memory) instead of mutating preexisting objects. * Strive to express your component's logic in the JSX you return. When you need to "change things", you'll usually want to do it in an event handler. As a last resort, you can `useEffect`. * Writing pure functions takes a bit of practice, but it unlocks the power of React's paradigm. @@ -231,7 +231,7 @@ Every new React feature we're building takes advantage of purity. From data fetc #### Fix a broken clock {/*fix-a-broken-clock*/} -This component tries to set the `<h1>`'s CSS class to `"night"` during the time from midnight to six hours in the morning, and `"day"` at all other times. However, it doesn't work. Can you fix this component? +This Component tries to set the `<h1>`'s CSS class to `"night"` during the time from midnight to six hours in the morning, and `"day"` at all other times. However, it doesn't work. Can you fix this component? You can verify whether your solution works by temporarily changing the computer's timezone. When the current time is between midnight and six in the morning, the clock should have inverted colors! @@ -301,7 +301,7 @@ body > * { <Solution> -You can fix this component by calculating the `className` and including it in the render output: +You can fix this Component by calculating the `className` and including it in the render output: <Sandpack> @@ -368,7 +368,7 @@ In this example, the side effect (modifying the DOM) was not necessary at all. Y #### Fix a broken profile {/*fix-a-broken-profile*/} -Two `Profile` components are rendered side by side with different data. Press "Collapse" on the first profile, and then "Expand" it. You'll notice that both profiles now show the same person. This is a bug. +Two `Profile` Components are rendered side by side with different data. Press "Collapse" on the first profile, and then "Expand" it. You'll notice that both profiles now show the same person. This is a bug. Find the cause of the bug and fix it. @@ -475,9 +475,9 @@ h1 { margin: 5px; font-size: 18px; } <Solution> -The problem is that the `Profile` component writes to a preexisting variable called `currentPerson`, and the `Header` and `Avatar` components read from it. This makes *all three of them* impure and difficult to predict. +The problem is that the `Profile` Component writes to a preexisting variable called `currentPerson`, and the `Header` and `Avatar` Components read from it. This makes *all three of them* impure and difficult to predict. -To fix the bug, remove the `currentPerson` variable. Instead, pass all information from `Profile` to `Header` and `Avatar` via props. You'll need to add a `person` prop to both components and pass it all the way down. +To fix the bug, remove the `currentPerson` variable. Instead, pass all information from `Profile` to `Header` and `Avatar` via props. You'll need to add a `person` prop to both Components and pass it all the way down. <Sandpack> @@ -571,13 +571,13 @@ h1 { margin: 5px; font-size: 18px; } </Sandpack> -Remember that React does not guarantee that component functions will execute in any particular order, so you can't communicate between them by setting variables. All communication must happen through props. +Remember that React does not guarantee that Component functions will execute in any particular order, so you can't communicate between them by setting variables. All communication must happen through props. </Solution> #### Fix a broken story tray {/*fix-a-broken-story-tray*/} -The CEO of your company is asking you to add "stories" to your online clock app, and you can't say no. You've written a `StoryTray` component that accepts a list of `stories`, followed by a "Create Story" placeholder. +The CEO of your company is asking you to add "stories" to your online clock app, and you can't say no. You've written a `StoryTray` Component that accepts a list of `stories`, followed by a "Create Story" placeholder. You implemented the "Create Story" placeholder by pushing one more fake story at the end of the `stories` array that you receive as a prop. But for some reason, "Create Story" appears more than once. Fix the issue. @@ -675,7 +675,7 @@ li { <Solution> -Notice how whenever the clock updates, "Create Story" is added *twice*. This serves as a hint that we have a mutation during rendering--Strict Mode calls components twice to make these issues more noticeable. +Notice how whenever the clock updates, "Create Story" is added *twice*. This serves as a hint that we have a mutation during rendering--Strict Mode calls Components twice to make these issues more noticeable. `StoryTray` function is not pure. By calling `push` on the received `stories` array (a prop!), it is mutating an object that was created *before* `StoryTray` started rendering. This makes it buggy and very difficult to predict. diff --git a/src/content/learn/lifecycle-of-reactive-effects.md b/src/content/learn/lifecycle-of-reactive-effects.md index 3dc9a75f02b..b399bf58af1 100644 --- a/src/content/learn/lifecycle-of-reactive-effects.md +++ b/src/content/learn/lifecycle-of-reactive-effects.md @@ -23,15 +23,15 @@ Effects have a different lifecycle from components. Components may mount, update ## The lifecycle of an Effect {/*the-lifecycle-of-an-effect*/} -Every React component goes through the same lifecycle: +Every React Component goes through the same lifecycle: -- A component _mounts_ when it's added to the screen. -- A component _updates_ when it receives new props or state, usually in response to an interaction. -- A component _unmounts_ when it's removed from the screen. +- A Component _mounts_ when it's added to the screen. +- A Component _updates_ when it receives new props or state, usually in response to an interaction. +- A Component _unmounts_ when it's removed from the screen. **It's a good way to think about components, but _not_ about Effects.** Instead, try to think about each Effect independently from your component's lifecycle. An Effect describes how to [synchronize an external system](/learn/synchronizing-with-effects) to the current props and state. As your code changes, synchronization will need to happen more or less often. -To illustrate this point, consider this Effect connecting your component to a chat server: +To illustrate this point, consider this Effect connecting your Component to a chat server: ```js const serverUrl = 'https://localhost:1234'; @@ -72,7 +72,7 @@ The cleanup function returned by your Effect specifies how to **stop synchronizi // ... ``` -Intuitively, you might think that React would **start synchronizing** when your component mounts and **stop synchronizing** when your component unmounts. However, this is not the end of the story! Sometimes, it may also be necessary to **start and stop synchronizing multiple times** while the component remains mounted. +Intuitively, you might think that React would **start synchronizing** when your Component mounts and **stop synchronizing** when your Component unmounts. However, this is not the end of the story! Sometimes, it may also be necessary to **start and stop synchronizing multiple times** while the Component remains mounted. Let's look at _why_ this is necessary, _when_ it happens, and _how_ you can control this behavior. @@ -84,7 +84,7 @@ Some Effects don't return a cleanup function at all. [More often than not,](/lea ### Why synchronization may need to happen more than once {/*why-synchronization-may-need-to-happen-more-than-once*/} -Imagine this `ChatRoom` component receives a `roomId` prop that the user picks in a dropdown. Let's say that initially the user picks the `"general"` room as the `roomId`. Your app displays the `"general"` chat room: +Imagine this `ChatRoom` Component receives a `roomId` prop that the user picks in a dropdown. Let's say that initially the user picks the `"general"` room as the `roomId`. Your app displays the `"general"` chat room: ```js {3} const serverUrl = 'https://localhost:1234'; @@ -131,7 +131,7 @@ At this point, you want React to do two things: ### How React re-synchronizes your Effect {/*how-react-re-synchronizes-your-effect*/} -Recall that your `ChatRoom` component has received a new value for its `roomId` prop. It used to be `"general"`, and now it is `"travel"`. React needs to re-synchronize your Effect to re-connect you to a different room. +Recall that your `ChatRoom` Component has received a new value for its `roomId` prop. It used to be `"general"`, and now it is `"travel"`. React needs to re-synchronize your Effect to re-connect you to a different room. To **stop synchronizing,** React will call the cleanup function that your Effect returned after connecting to the `"general"` room. Since `roomId` was `"general"`, the cleanup function disconnects from the `"general"` room: @@ -158,7 +158,7 @@ function ChatRoom({ roomId /* "travel" */ }) { Thanks to this, you're now connected to the same room that the user chose in the UI. Disaster averted! -Every time after your component re-renders with a different `roomId`, your Effect will re-synchronize. For example, let's say the user changes `roomId` from `"travel"` to `"music"`. React will again **stop synchronizing** your Effect by calling its cleanup function (disconnecting you from the `"travel"` room). Then it will **start synchronizing** again by running its body with the new `roomId` prop (connecting you to the `"music"` room). +Every time after your Component re-renders with a different `roomId`, your Effect will re-synchronize. For example, let's say the user changes `roomId` from `"travel"` to `"music"`. React will again **stop synchronizing** your Effect by calling its cleanup function (disconnecting you from the `"travel"` room). Then it will **start synchronizing** again by running its body with the new `roomId` prop (connecting you to the `"music"` room). Finally, when the user goes to a different screen, `ChatRoom` unmounts. Now there is no need to stay connected at all. React will **stop synchronizing** your Effect one last time and disconnect you from the `"music"` chat room. @@ -200,9 +200,9 @@ This code's structure might inspire you to see what happened as a sequence of no Previously, you were thinking from the component's perspective. When you looked from the component's perspective, it was tempting to think of Effects as "callbacks" or "lifecycle events" that fire at a specific time like "after a render" or "before unmount". This way of thinking gets complicated very fast, so it's best to avoid. -**Instead, always focus on a single start/stop cycle at a time. It shouldn't matter whether a component is mounting, updating, or unmounting. All you need to do is to describe how to start synchronization and how to stop it. If you do it well, your Effect will be resilient to being started and stopped as many times as it's needed.** +**Instead, always focus on a single start/stop cycle at a time. It shouldn't matter whether a Component is mounting, updating, or unmounting. All you need to do is to describe how to start synchronization and how to stop it. If you do it well, your Effect will be resilient to being started and stopped as many times as it's needed.** -This might remind you how you don't think whether a component is mounting or updating when you write the rendering logic that creates JSX. You describe what should be on the screen, and React [figures out the rest.](/learn/reacting-to-input-with-state) +This might remind you how you don't think whether a Component is mounting or updating when you write the rendering logic that creates JSX. You describe what should be on the screen, and React [figures out the rest.](/learn/reacting-to-input-with-state) ### How React verifies that your Effect can re-synchronize {/*how-react-verifies-that-your-effect-can-re-synchronize*/} @@ -272,13 +272,13 @@ button { margin-left: 10px; } </Sandpack> -Notice that when the component mounts for the first time, you see three logs: +Notice that when the Component mounts for the first time, you see three logs: 1. `✅ Connecting to "general" room at https://localhost:1234...` *(development-only)* 1. `❌ Disconnected from "general" room at https://localhost:1234.` *(development-only)* 1. `✅ Connecting to "general" room at https://localhost:1234...` -The first two logs are development-only. In development, React always remounts each component once. +The first two logs are development-only. In development, React always remounts each Component once. **React verifies that your Effect can re-synchronize by forcing it to do that immediately in development.** This might remind you of opening a door and closing it an extra time to check if the door lock works. React starts and stops your Effect one extra time in development to check [you've implemented its cleanup well.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) @@ -308,9 +308,9 @@ Here's how this works: 2. You knew that your Effect reads `roomId` (so its logic depends on a value that may change later). 3. This is why you specified it as your Effect's dependency (so that it re-synchronizes when `roomId` changes). -Every time after your component re-renders, React will look at the array of dependencies that you have passed. If any of the values in the array is different from the value at the same spot that you passed during the previous render, React will re-synchronize your Effect. +Every time after your Component re-renders, React will look at the array of dependencies that you have passed. If any of the values in the array is different from the value at the same spot that you passed during the previous render, React will re-synchronize your Effect. -For example, if you passed `["general"]` during the initial render, and later you passed `["travel"]` during the next render, React will compare `"general"` and `"travel"`. These are different values (compared with [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)), so React will re-synchronize your Effect. On the other hand, if your component re-renders but `roomId` has not changed, your Effect will remain connected to the same room. +For example, if you passed `["general"]` during the initial render, and later you passed `["travel"]` during the next render, React will compare `"general"` and `"travel"`. These are different values (compared with [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)), so React will re-synchronize your Effect. On the other hand, if your Component re-renders but `roomId` has not changed, your Effect will remain connected to the same room. ### Each Effect represents a separate synchronization process {/*each-effect-represents-a-separate-synchronization-process*/} @@ -371,9 +371,9 @@ function ChatRoom({ roomId }) { Why doesn't `serverUrl` need to be a dependency? -This is because the `serverUrl` never changes due to a re-render. It's always the same no matter how many times the component re-renders and why. Since `serverUrl` never changes, it wouldn't make sense to specify it as a dependency. After all, dependencies only do something when they change over time! +This is because the `serverUrl` never changes due to a re-render. It's always the same no matter how many times the Component re-renders and why. Since `serverUrl` never changes, it wouldn't make sense to specify it as a dependency. After all, dependencies only do something when they change over time! -On the other hand, `roomId` may be different on a re-render. **Props, state, and other values declared inside the component are _reactive_ because they're calculated during rendering and participate in the React data flow.** +On the other hand, `roomId` may be different on a re-render. **Props, state, and other values declared inside the Component are _reactive_ because they're calculated during rendering and participate in the React data flow.** If `serverUrl` was a state variable, it would be reactive. Reactive values must be included in dependencies: @@ -492,7 +492,7 @@ function ChatRoom() { Now your Effect's code does not use *any* reactive values, so its dependencies can be empty (`[]`). -Thinking from the component's perspective, the empty `[]` dependency array means this Effect connects to the chat room only when the component mounts, and disconnects only when the component unmounts. (Keep in mind that React would still [re-synchronize it an extra time](#how-react-verifies-that-your-effect-can-re-synchronize) in development to stress-test your logic.) +Thinking from the component's perspective, the empty `[]` dependency array means this Effect connects to the chat room only when the Component mounts, and disconnects only when the Component unmounts. (Keep in mind that React would still [re-synchronize it an extra time](#how-react-verifies-that-your-effect-can-re-synchronize) in development to stress-test your logic.) <Sandpack> @@ -550,9 +550,9 @@ button { margin-left: 10px; } However, if you [think from the Effect's perspective,](#thinking-from-the-effects-perspective) you don't need to think about mounting and unmounting at all. What's important is you've specified what your Effect does to start and stop synchronizing. Today, it has no reactive dependencies. But if you ever want the user to change `roomId` or `serverUrl` over time (and they would become reactive), your Effect's code won't change. You will only need to add them to the dependencies. -### All variables declared in the component body are reactive {/*all-variables-declared-in-the-component-body-are-reactive*/} +### All variables declared in the Component body are reactive {/*all-variables-declared-in-the-component-body-are-reactive*/} -Props and state aren't the only reactive values. Values that you calculate from them are also reactive. If the props or state change, your component will re-render, and the values calculated from them will also change. This is why all variables from the component body used by the Effect should be in the Effect dependency list. +Props and state aren't the only reactive values. Values that you calculate from them are also reactive. If the props or state change, your Component will re-render, and the values calculated from them will also change. This is why all variables from the Component body used by the Effect should be in the Effect dependency list. Let's say that the user can pick a chat server in the dropdown, but they can also configure a default server in settings. Suppose you've already put the settings state in a [context](/learn/scaling-up-with-reducer-and-context) so you read the `settings` from that context. Now you calculate the `serverUrl` based on the selected server from props and the default server: @@ -573,9 +573,9 @@ function ChatRoom({ roomId, selectedServerUrl }) { // roomId is reactive In this example, `serverUrl` is not a prop or a state variable. It's a regular variable that you calculate during rendering. But it's calculated during rendering, so it can change due to a re-render. This is why it's reactive. -**All values inside the component (including props, state, and variables in your component's body) are reactive. Any reactive value can change on a re-render, so you need to include reactive values as Effect's dependencies.** +**All values inside the Component (including props, state, and variables in your component's body) are reactive. Any reactive value can change on a re-render, so you need to include reactive values as Effect's dependencies.** -In other words, Effects "react" to all values from the component body. +In other words, Effects "react" to all values from the Component body. <DeepDive> @@ -766,7 +766,7 @@ On the [next](/learn/separating-events-from-effects) [pages](/learn/removing-eff - Each Effect has a separate lifecycle from the surrounding component. - Each Effect describes a separate synchronization process that can *start* and *stop*. - When you write and read Effects, think from each individual Effect's perspective (how to start and stop synchronization) rather than from the component's perspective (how it mounts, updates, or unmounts). -- Values declared inside the component body are "reactive". +- Values declared inside the Component body are "reactive". - Reactive values should re-synchronize the Effect because they can change over time. - The linter verifies that all reactive values used inside the Effect are specified as dependencies. - All errors flagged by the linter are legitimate. There's always a way to fix the code to not break the rules. @@ -777,7 +777,7 @@ On the [next](/learn/separating-events-from-effects) [pages](/learn/removing-eff #### Fix reconnecting on every keystroke {/*fix-reconnecting-on-every-keystroke*/} -In this example, the `ChatRoom` component connects to the chat room when the component mounts, disconnects when it unmounts, and reconnects when you select a different chat room. This behavior is correct, so you need to keep it working. +In this example, the `ChatRoom` Component connects to the chat room when the Component mounts, disconnects when it unmounts, and reconnects when you select a different chat room. This behavior is correct, so you need to keep it working. However, there is a problem. Whenever you type into the message box input at the bottom, `ChatRoom` *also* reconnects to the chat. (You can notice this by clearing the console and typing into the input.) Fix the issue so that this doesn't happen. @@ -1187,7 +1187,7 @@ body { <Solution> -The problem with the original code was suppressing the dependency linter. If you remove the suppression, you'll see that this Effect depends on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time! +The problem with the original code was suppressing the dependency linter. If you remove the suppression, you'll see that this Effect depends on the `handleMove` function. This makes sense: `handleMove` is declared inside the Component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time! The author of the original code has "lied" to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value. @@ -1317,7 +1317,7 @@ You'll learn a more general approach to this type of problem in [Separating Even #### Fix a connection switch {/*fix-a-connection-switch*/} -In this example, the chat service in `chat.js` exposes two different APIs: `createEncryptedConnection` and `createUnencryptedConnection`. The root `App` component lets the user choose whether to use encryption or not, and then passes down the corresponding API method to the child `ChatRoom` component as the `createConnection` prop. +In this example, the chat service in `chat.js` exposes two different APIs: `createEncryptedConnection` and `createUnencryptedConnection`. The root `App` Component lets the user choose whether to use encryption or not, and then passes down the corresponding API method to the child `ChatRoom` Component as the `createConnection` prop. Notice that initially, the console logs say the connection is not encrypted. Try toggling the checkbox on: nothing will happen. However, if you change the selected room after that, then the chat will reconnect *and* enable encryption (as you'll see from the console messages). This is a bug. Fix the bug so that toggling the checkbox *also* causes the chat to reconnect. @@ -1423,7 +1423,7 @@ label { display: block; margin-bottom: 10px; } <Solution> -If you remove the linter suppression, you will see a lint error. The problem is that `createConnection` is a prop, so it's a reactive value. It can change over time! (And indeed, it should--when the user ticks the checkbox, the parent component passes a different value of the `createConnection` prop.) This is why it should be a dependency. Include it in the list to fix the bug: +If you remove the linter suppression, you will see a lint error. The problem is that `createConnection` is a prop, so it's a reactive value. It can change over time! (And indeed, it should--when the user ticks the checkbox, the parent Component passes a different value of the `createConnection` prop.) This is why it should be a dependency. Include it in the list to fix the bug: <Sandpack> @@ -1518,7 +1518,7 @@ label { display: block; margin-bottom: 10px; } </Sandpack> -It is correct that `createConnection` is a dependency. However, this code is a bit fragile because someone could edit the `App` component to pass an inline function as the value of this prop. In that case, its value would be different every time the `App` component re-renders, so the Effect might re-synchronize too often. To avoid this, you can pass `isEncrypted` down instead: +It is correct that `createConnection` is a dependency. However, this code is a bit fragile because someone could edit the `App` Component to pass an inline function as the value of this prop. In that case, its value would be different every time the `App` Component re-renders, so the Effect might re-synchronize too often. To avoid this, you can pass `isEncrypted` down instead: <Sandpack> @@ -1613,7 +1613,7 @@ label { display: block; margin-bottom: 10px; } </Sandpack> -In this version, the `App` component passes a boolean prop instead of a function. Inside the Effect, you decide which function to use. Since both `createEncryptedConnection` and `createUnencryptedConnection` are declared outside the component, they aren't reactive, and don't need to be dependencies. You'll learn more about this in [Removing Effect Dependencies.](/learn/removing-effect-dependencies) +In this version, the `App` Component passes a boolean prop instead of a function. Inside the Effect, you decide which function to use. Since both `createEncryptedConnection` and `createUnencryptedConnection` are declared outside the component, they aren't reactive, and don't need to be dependencies. You'll learn more about this in [Removing Effect Dependencies.](/learn/removing-effect-dependencies) </Solution> @@ -2102,7 +2102,7 @@ label { display: block; margin-bottom: 10px; } </Sandpack> -Check the `useSelectOptions.js` tab in the sandbox to see how it works. Ideally, most Effects in your application should eventually be replaced by custom Hooks, whether written by you or by the community. Custom Hooks hide the synchronization logic, so the calling component doesn't know about the Effect. As you keep working on your app, you'll develop a palette of Hooks to choose from, and eventually you won't need to write Effects in your components very often. +Check the `useSelectOptions.js` tab in the sandbox to see how it works. Ideally, most Effects in your application should eventually be replaced by custom Hooks, whether written by you or by the community. Custom Hooks hide the synchronization logic, so the calling Component doesn't know about the Effect. As you keep working on your app, you'll develop a palette of Hooks to choose from, and eventually you won't need to write Effects in your Components very often. </Solution> diff --git a/src/content/learn/managing-state.md b/src/content/learn/managing-state.md index 93bcc10fd61..d1f4560a0c0 100644 --- a/src/content/learn/managing-state.md +++ b/src/content/learn/managing-state.md @@ -22,7 +22,7 @@ As your application grows, it helps to be more intentional about how your state ## Reacting to input with state {/*reacting-to-input-with-state*/} -With React, you won't modify the UI from code directly. For example, you won't write commands like "disable the button", "enable the button", "show the success message", etc. Instead, you will describe the UI you want to see for the different visual states of your component ("initial state", "typing state", "success state"), and then trigger the state changes in response to user input. This is similar to how designers think about UI. +With React, you won't modify the UI from code directly. For example, you won't write commands like "disable the button", "enable the button", "show the success message", etc. Instead, you will describe the UI you want to see for the different visual states of your Component ("initial state", "typing state", "success state"), and then trigger the state changes in response to user input. This is similar to how designers think about UI. Here is a quiz form built using React. Note how it uses the `status` state variable to determine whether to enable or disable the submit button, and whether to show the success message instead. @@ -114,7 +114,7 @@ Read **[Reacting to Input with State](/learn/reacting-to-input-with-state)** to ## Choosing the state structure {/*choosing-the-state-structure*/} -Structuring state well can make a difference between a component that is pleasant to modify and debug, and one that is a constant source of bugs. The most important principle is that state shouldn't contain redundant or duplicated information. If there's unnecessary state, it's easy to forget to update it, and introduce bugs! +Structuring state well can make a difference between a Component that is pleasant to modify and debug, and one that is a constant source of bugs. The most important principle is that state shouldn't contain redundant or duplicated information. If there's unnecessary state, it's easy to forget to update it, and introduce bugs! For example, this form has a **redundant** `fullName` state variable: @@ -169,7 +169,7 @@ label { display: block; margin-bottom: 5px; } </Sandpack> -You can remove it and simplify the code by calculating `fullName` while the component is rendering: +You can remove it and simplify the code by calculating `fullName` while the Component is rendering: <Sandpack> @@ -229,11 +229,11 @@ Read **[Choosing the State Structure](/learn/choosing-the-state-structure)** to </LearnMore> -## Sharing state between components {/*sharing-state-between-components*/} +## Sharing state between Components {/*sharing-state-between-components*/} -Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as "lifting state up", and it's one of the most common things you will do writing React code. +Sometimes, you want the state of two Components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as "lifting state up", and it's one of the most common things you will do writing React code. -In this example, only one panel should be active at a time. To achieve this, instead of keeping the active state inside each individual panel, the parent component holds the state and specifies the props for its children. +In this example, only one panel should be active at a time. To achieve this, instead of keeping the active state inside each individual panel, the parent Component holds the state and specifies the props for its children. <Sandpack> @@ -296,13 +296,13 @@ h3, p { margin: 5px 0px; } <LearnMore path="/learn/sharing-state-between-components"> -Read **[Sharing State Between Components](/learn/sharing-state-between-components)** to learn how to lift state up and keep components in sync. +Read **[Sharing State Between Components](/learn/sharing-state-between-components)** to learn how to lift state up and keep Components in sync. </LearnMore> ## Preserving and resetting state {/*preserving-and-resetting-state*/} -When you re-render a component, React needs to decide which parts of the tree to keep (and update), and which parts to discard or re-create from scratch. In most cases, React's automatic behavior works well enough. By default, React preserves the parts of the tree that "match up" with the previously rendered component tree. +When you re-render a component, React needs to decide which parts of the tree to keep (and update), and which parts to discard or re-create from scratch. In most cases, React's automatic behavior works well enough. By default, React preserves the parts of the tree that "match up" with the previously rendered Component tree. However, sometimes this is not what you want. In this chat app, typing a message and then switching the recipient does not reset the input. This can make the user accidentally send a message to the wrong person: @@ -399,7 +399,7 @@ textarea { </Sandpack> -React lets you override the default behavior, and *force* a component to reset its state by passing it a different `key`, like `<Chat key={email} />`. This tells React that if the recipient is different, it should be considered a *different* `Chat` component that needs to be re-created from scratch with the new data (and UI like inputs). Now switching between the recipients resets the input field--even though you render the same component. +React lets you override the default behavior, and *force* a Component to reset its state by passing it a different `key`, like `<Chat key={email} />`. This tells React that if the recipient is different, it should be considered a *different* `Chat` Component that needs to be re-created from scratch with the new data (and UI like inputs). Now switching between the recipients resets the input field--even though you render the same component. <Sandpack> @@ -502,7 +502,7 @@ Read **[Preserving and Resetting State](/learn/preserving-and-resetting-state)** ## Extracting state logic into a reducer {/*extracting-state-logic-into-a-reducer*/} -Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your component in a single function, called "reducer". Your event handlers become concise because they only specify the user "actions". At the bottom of the file, the reducer function specifies how the state should update in response to each action! +Components with many state updates spread across many event handlers can get overwhelming. For these cases, you can consolidate all the state update logic outside your Component in a single function, called "reducer". Your event handlers become concise because they only specify the user "actions". At the bottom of the file, the reducer function specifies how the state should update in response to each action! <Sandpack> @@ -699,9 +699,9 @@ Read **[Extracting State Logic into a Reducer](/learn/extracting-state-logic-int ## Passing data deeply with context {/*passing-data-deeply-with-context*/} -Usually, you will pass information from a parent component to a child component via props. But passing props can become inconvenient if you need to pass some prop through many components, or if many components need the same information. Context lets the parent component make some information available to any component in the tree below it—no matter how deep it is—without passing it explicitly through props. +Usually, you will pass information from a parent Component to a child Component via props. But passing props can become inconvenient if you need to pass some prop through many components, or if many Components need the same information. Context lets the parent Component make some information available to any Component in the tree below it—no matter how deep it is—without passing it explicitly through props. -Here, the `Heading` component determines its heading level by "asking" the closest `Section` for its level. Each `Section` tracks its own level by asking the parent `Section` and adding one to it. Every `Section` provides information to all components below it without passing props--it does that through context. +Here, the `Heading` Component determines its heading level by "asking" the closest `Section` for its level. Each `Section` tracks its own level by asking the parent `Section` and adding one to it. Every `Section` provides information to all Components below it without passing props--it does that through context. <Sandpack> @@ -803,7 +803,7 @@ Read **[Passing Data Deeply with Context](/learn/passing-data-deeply-with-contex Reducers let you consolidate a component’s state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen. -With this approach, a parent component with complex state manages it with a reducer. Other components anywhere deep in the tree can read its state via context. They can also dispatch actions to update that state. +With this approach, a parent Component with complex state manages it with a reducer. Other Components anywhere deep in the tree can read its state via context. They can also dispatch actions to update that state. <Sandpack> diff --git a/src/content/learn/manipulating-the-dom-with-refs.md b/src/content/learn/manipulating-the-dom-with-refs.md index bc9a3eac472..6b9d9e4b793 100644 --- a/src/content/learn/manipulating-the-dom-with-refs.md +++ b/src/content/learn/manipulating-the-dom-with-refs.md @@ -4,7 +4,7 @@ title: 'Manipulating the DOM with Refs' <Intro> -React automatically updates the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) to match your render output, so your components won't often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React--for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a *ref* to the DOM node. +React automatically updates the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model/Introduction) to match your render output, so your Components won't often need to manipulate it. However, sometimes you might need access to the DOM elements managed by React--for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a *ref* to the DOM node. </Intro> @@ -342,7 +342,7 @@ This lets you read individual DOM nodes from the Map later. ## Accessing another component's DOM nodes {/*accessing-another-components-dom-nodes*/} -When you put a ref on a built-in component that outputs a browser element like `<input />`, React will set that ref's `current` property to the corresponding DOM node (such as the actual `<input />` in the browser). +When you put a ref on a built-in Component that outputs a browser element like `<input />`, React will set that ref's `current` property to the corresponding DOM node (such as the actual `<input />` in the browser). However, if you try to put a ref on **your own** component, like `<MyInput />`, by default you will get `null`. Here is an example demonstrating it. Notice how clicking the button **does not** focus the input: @@ -379,13 +379,13 @@ To help you notice the issue, React also prints an error to the console: <ConsoleBlock level="error"> -Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? +Warning: Function Components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()? </ConsoleBlock> -This happens because by default React does not let a component access the DOM nodes of other components. Not even for its own children! This is intentional. Refs are an escape hatch that should be used sparingly. Manually manipulating _another_ component's DOM nodes makes your code even more fragile. +This happens because by default React does not let a Component access the DOM nodes of other components. Not even for its own children! This is intentional. Refs are an escape hatch that should be used sparingly. Manually manipulating _another_ component's DOM nodes makes your code even more fragile. -Instead, components that _want_ to expose their DOM nodes have to **opt in** to that behavior. A component can specify that it "forwards" its ref to one of its children. Here's how `MyInput` can use the `forwardRef` API: +Instead, Components that _want_ to expose their DOM nodes have to **opt in** to that behavior. A Component can specify that it "forwards" its ref to one of its children. Here's how `MyInput` can use the `forwardRef` API: ```js const MyInput = forwardRef((props, ref) => { @@ -395,8 +395,8 @@ const MyInput = forwardRef((props, ref) => { This is how it works: -1. `<MyInput ref={inputRef} />` tells React to put the corresponding DOM node into `inputRef.current`. However, it's up to the `MyInput` component to opt into that--by default, it doesn't. -2. The `MyInput` component is declared using `forwardRef`. **This opts it into receiving the `inputRef` from above as the second `ref` argument** which is declared after `props`. +1. `<MyInput ref={inputRef} />` tells React to put the corresponding DOM node into `inputRef.current`. However, it's up to the `MyInput` Component to opt into that--by default, it doesn't. +2. The `MyInput` Component is declared using `forwardRef`. **This opts it into receiving the `inputRef` from above as the second `ref` argument** which is declared after `props`. 3. `MyInput` itself passes the `ref` it received to the `<input>` inside of it. Now clicking the button to focus the input works: @@ -430,13 +430,13 @@ export default function Form() { </Sandpack> -In design systems, it is a common pattern for low-level components like buttons, inputs, and so on, to forward their refs to their DOM nodes. On the other hand, high-level components like forms, lists, or page sections usually won't expose their DOM nodes to avoid accidental dependencies on the DOM structure. +In design systems, it is a common pattern for low-level Components like buttons, inputs, and so on, to forward their refs to their DOM nodes. On the other hand, high-level Components like forms, lists, or page sections usually won't expose their DOM nodes to avoid accidental dependencies on the DOM structure. <DeepDive> #### Exposing a subset of the API with an imperative handle {/*exposing-a-subset-of-the-api-with-an-imperative-handle*/} -In the above example, `MyInput` exposes the original DOM input element. This lets the parent component call `focus()` on it. However, this also lets the parent component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with `useImperativeHandle`: +In the above example, `MyInput` exposes the original DOM input element. This lets the parent Component call `focus()` on it. However, this also lets the parent Component do something else--for example, change its CSS styles. In uncommon cases, you may want to restrict the exposed functionality. You can do that with `useImperativeHandle`: <Sandpack> @@ -478,7 +478,7 @@ export default function Form() { </Sandpack> -Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, `useImperativeHandle` instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside `useImperativeHandle` call. +Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, `useImperativeHandle` instructs React to provide your own special object as the value of a ref to the parent component. So `inputRef.current` inside the `Form` Component will only have the `focus` method. In this case, the ref "handle" is not the DOM node, but the custom object you create inside `useImperativeHandle` call. </DeepDive> @@ -486,7 +486,7 @@ Here, `realInputRef` inside `MyInput` holds the actual input DOM node. However, In React, every update is split in [two phases](/learn/render-and-commit#step-3-react-commits-changes-to-the-dom): -* During **render,** React calls your components to figure out what should be on the screen. +* During **render,** React calls your Components to figure out what should be on the screen. * During **commit,** React applies changes to the DOM. In general, you [don't want](/learn/referencing-values-with-refs#best-practices-for-refs) to access refs during rendering. That goes for refs holding DOM nodes as well. During the first render, the DOM nodes have not yet been created, so `ref.current` will be `null`. And during the rendering of updates, the DOM nodes haven't been updated yet. So it's too early to read them. @@ -690,7 +690,7 @@ However, this doesn't mean that you can't do it at all. It requires caution. **Y - Refs are a generic concept, but most often you'll use them to hold DOM elements. - You instruct React to put a DOM node into `myRef.current` by passing `<div ref={myRef}>`. - Usually, you will use refs for non-destructive actions like focusing, scrolling, or measuring DOM elements. -- A component doesn't expose its DOM nodes by default. You can opt into exposing a DOM node by using `forwardRef` and passing the second `ref` argument down to a specific node. +- A Component doesn't expose its DOM nodes by default. You can opt into exposing a DOM node by using `forwardRef` and passing the second `ref` argument down to a specific node. - Avoid changing DOM nodes managed by React. - If you do modify DOM nodes managed by React, modify parts that React has no reason to update. @@ -1086,13 +1086,13 @@ img { </Solution> -#### Focus the search field with separate components {/*focus-the-search-field-with-separate-components*/} +#### Focus the search field with separate Components {/*focus-the-search-field-with-separate-components*/} -Make it so that clicking the "Search" button puts focus into the field. Note that each component is defined in a separate file and shouldn't be moved out of it. How do you connect them together? +Make it so that clicking the "Search" button puts focus into the field. Note that each Component is defined in a separate file and shouldn't be moved out of it. How do you connect them together? <Hint> -You'll need `forwardRef` to opt into exposing a DOM node from your own component like `SearchInput`. +You'll need `forwardRef` to opt into exposing a DOM node from your own Component like `SearchInput`. </Hint> diff --git a/src/content/learn/passing-data-deeply-with-context.md b/src/content/learn/passing-data-deeply-with-context.md index 1aea87b354f..fbaa98d4805 100644 --- a/src/content/learn/passing-data-deeply-with-context.md +++ b/src/content/learn/passing-data-deeply-with-context.md @@ -4,7 +4,7 @@ title: Passing Data Deeply with Context <Intro> -Usually, you will pass information from a parent component to a child component via props. But passing props can become verbose and inconvenient if you have to pass them through many components in the middle, or if many components in your app need the same information. *Context* lets the parent component make some information available to any component in the tree below it—no matter how deep—without passing it explicitly through props. +Usually, you will pass information from a parent Component to a child Component via props. But passing props can become verbose and inconvenient if you have to pass them through many Components in the middle, or if many Components in your app need the same information. *Context* lets the parent Component make some information available to any Component in the tree below it—no matter how deep—without passing it explicitly through props. </Intro> @@ -19,9 +19,9 @@ Usually, you will pass information from a parent component to a child component ## The problem with passing props {/*the-problem-with-passing-props*/} -[Passing props](/learn/passing-props-to-a-component) is a great way to explicitly pipe data through your UI tree to the components that use it. +[Passing props](/learn/passing-props-to-a-component) is a great way to explicitly pipe data through your UI tree to the Components that use it. -But passing props can become verbose and inconvenient when you need to pass some prop deeply through the tree, or if many components need the same prop. The nearest common ancestor could be far removed from the components that need data, and [lifting state up](/learn/sharing-state-between-components) that high can lead to a situation called "prop drilling". +But passing props can become verbose and inconvenient when you need to pass some prop deeply through the tree, or if many Components need the same prop. The nearest common ancestor could be far removed from the Components that need data, and [lifting state up](/learn/sharing-state-between-components) that high can lead to a situation called "prop drilling". <DiagramGroup> @@ -38,11 +38,11 @@ Prop drilling </DiagramGroup> -Wouldn't it be great if there were a way to "teleport" data to the components in the tree that need it without passing props? With React's context feature, there is! +Wouldn't it be great if there were a way to "teleport" data to the Components in the tree that need it without passing props? With React's context feature, there is! ## Context: an alternative to passing props {/*context-an-alternative-to-passing-props*/} -Context lets a parent component provide data to the entire tree below it. There are many uses for context. Here is one example. Consider this `Heading` component that accepts a `level` for its size: +Context lets a parent Component provide data to the entire tree below it. There are many uses for context. Here is one example. Consider this `Heading` Component that accepts a `level` for its size: <Sandpack> @@ -190,7 +190,7 @@ Currently, you pass the `level` prop to each `<Heading>` separately: </Section> ``` -It would be nice if you could pass the `level` prop to the `<Section>` component instead and remove it from the `<Heading>`. This way you could enforce that all headings in the same section have the same size: +It would be nice if you could pass the `level` prop to the `<Section>` Component instead and remove it from the `<Heading>`. This way you could enforce that all headings in the same section have the same size: ```js <Section level={3}> @@ -200,13 +200,13 @@ It would be nice if you could pass the `level` prop to the `<Section>` component </Section> ``` -But how can the `<Heading>` component know the level of its closest `<Section>`? **That would require some way for a child to "ask" for data from somewhere above in the tree.** +But how can the `<Heading>` Component know the level of its closest `<Section>`? **That would require some way for a child to "ask" for data from somewhere above in the tree.** You can't do it with props alone. This is where context comes into play. You will do it in three steps: 1. **Create** a context. (You can call it `LevelContext`, since it's for the heading level.) -2. **Use** that context from the component that needs the data. (`Heading` will use `LevelContext`.) -3. **Provide** that context from the component that specifies the data. (`Section` will provide `LevelContext`.) +2. **Use** that context from the Component that needs the data. (`Heading` will use `LevelContext`.) +3. **Provide** that context from the Component that specifies the data. (`Section` will provide `LevelContext`.) Context lets a parent--even a distant one!--provide some data to the entire tree inside of it. @@ -218,7 +218,7 @@ Using context in close children </Diagram> -<Diagram name="passing_data_context_far" height={430} width={608} captionPosition="top" alt="Diagram with a tree of ten nodes, each node with two children or less. The root parent node contains a bubble representing a value highlighted in orange. The value projects down directly to four leaves and one intermediate component in the tree, which are all highlighted in orange. None of the other intermediate components are highlighted."> +<Diagram name="passing_data_context_far" height={430} width={608} captionPosition="top" alt="Diagram with a tree of ten nodes, each node with two children or less. The root parent node contains a bubble representing a value highlighted in orange. The value projects down directly to four leaves and one intermediate Component in the tree, which are all highlighted in orange. None of the other intermediate Components are highlighted."> Using context in distant children @@ -228,7 +228,7 @@ Using context in distant children ### Step 1: Create the context {/*step-1-create-the-context*/} -First, you need to create the context. You'll need to **export it from a file** so that your components can use it: +First, you need to create the context. You'll need to **export it from a file** so that your Components can use it: <Sandpack> @@ -319,7 +319,7 @@ import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; ``` -Currently, the `Heading` component reads `level` from props: +Currently, the `Heading` Component reads `level` from props: ```js export default function Heading({ level, children }) { @@ -336,9 +336,9 @@ export default function Heading({ children }) { } ``` -`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React component (not inside loops or conditions). **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.** +`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook immediately inside a React Component (not inside loops or conditions). **`useContext` tells React that the `Heading` Component wants to read the `LevelContext`.** -Now that the `Heading` component doesn't have a `level` prop, you don't need to pass the level prop to `Heading` in your JSX like this anymore: +Now that the `Heading` Component doesn't have a `level` prop, you don't need to pass the level prop to `Heading` in your JSX like this anymore: ```js <Section> @@ -448,7 +448,7 @@ If you don't provide the context, React will use the default value you've specif ### Step 3: Provide the context {/*step-3-provide-the-context*/} -The `Section` component currently renders its children: +The `Section` Component currently renders its children: ```js export default function Section({ children }) { @@ -476,7 +476,7 @@ export default function Section({ level, children }) { } ``` -This tells React: "if any component inside this `<Section>` asks for `LevelContext`, give them this `level`." The component will use the value of the nearest `<LevelContext.Provider>` in the UI tree above it. +This tells React: "if any Component inside this `<Section>` asks for `LevelContext`, give them this `level`." The Component will use the value of the nearest `<LevelContext.Provider>` in the UI tree above it. <Sandpack> @@ -570,7 +570,7 @@ It's the same result as the original code, but you did not need to pass the `lev 2. `Section` wraps its children into `<LevelContext.Provider value={level}>`. 3. `Heading` asks the closest value of `LevelContext` above with `useContext(LevelContext)`. -## Using and providing context from the same component {/*using-and-providing-context-from-the-same-component*/} +## Using and providing context from the same Component {/*using-and-providing-context-from-the-same-component*/} Currently, you still have to specify each section's `level` manually: @@ -585,7 +585,7 @@ export default function Page() { ... ``` -Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it: +Since context lets you read information from a Component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it: ```js src/Section.js {5,8} import { useContext } from 'react'; @@ -699,15 +699,15 @@ Now both `Heading` and `Section` read the `LevelContext` to figure out how "deep <Note> -This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on. +This example uses heading levels because they show visually how nested Components can override context. But context is useful for many other use cases too. You can pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on. </Note> -## Context passes through intermediate components {/*context-passes-through-intermediate-components*/} +## Context passes through intermediate Components {/*context-passes-through-intermediate-components*/} -You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `<div>` and components you might build yourself. +You can insert as many Components as you like between the Component that provides context and the one that uses it. This includes both built-in Components like `<div>` and Components you might build yourself. -In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `<Heading>` inside of it gets its level automatically from the closest `<Section>`: +In this example, the same `Post` Component (with a dashed border) is rendered at two different nesting levels. Notice that the `<Heading>` inside of it gets its level automatically from the closest `<Section>`: <Sandpack> @@ -834,11 +834,11 @@ export const LevelContext = createContext(0); You didn't do anything special for this to work. A `Section` specifies the context for the tree inside it, so you can insert a `<Heading>` anywhere, and it will have the correct size. Try it in the sandbox above! -**Context lets you write components that "adapt to their surroundings" and display themselves differently depending on _where_ (or, in other words, _in which context_) they are being rendered.** +**Context lets you write Components that "adapt to their surroundings" and display themselves differently depending on _where_ (or, in other words, _in which context_) they are being rendered.** How context works might remind you of [CSS property inheritance.](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance) In CSS, you can specify `color: blue` for a `<div>`, and any DOM node inside of it, no matter how deep, will inherit that color unless some other DOM node in the middle overrides it with `color: green`. Similarly, in React, the only way to override some context coming from above is to wrap children into a context provider with a different value. -In CSS, different properties like `color` and `background-color` don't override each other. You can set all `<div>`'s `color` to red without impacting `background-color`. Similarly, **different React contexts don't override each other.** Each context that you make with `createContext()` is completely separate from other ones, and ties together components using and providing *that particular* context. One component may use or provide many different contexts without a problem. +In CSS, different properties like `color` and `background-color` don't override each other. You can set all `<div>`'s `color` to red without impacting `background-color`. Similarly, **different React contexts don't override each other.** Each context that you make with `createContext()` is completely separate from other ones, and ties together Components using and providing *that particular* context. One Component may use or provide many different contexts without a problem. ## Before you use context {/*before-you-use-context*/} @@ -846,31 +846,31 @@ Context is very tempting to use! However, this also means it's too easy to overu Here's a few alternatives you should consider before using context: -1. **Start by [passing props.](/learn/passing-props-to-a-component)** If your components are not trivial, it's not unusual to pass a dozen props down through a dozen components. It may feel like a slog, but it makes it very clear which components use which data! The person maintaining your code will be glad you've made the data flow explicit with props. -2. **Extract components and [pass JSX as `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) to them.** If you pass some data through many layers of intermediate components that don't use that data (and only pass it further down), this often means that you forgot to extract some components along the way. For example, maybe you pass data props like `posts` to visual components that don't use them directly, like `<Layout posts={posts} />`. Instead, make `Layout` take `children` as a prop, and render `<Layout><Posts posts={posts} /></Layout>`. This reduces the number of layers between the component specifying the data and the one that needs it. +1. **Start by [passing props.](/learn/passing-props-to-a-component)** If your Components are not trivial, it's not unusual to pass a dozen props down through a dozen components. It may feel like a slog, but it makes it very clear which Components use which data! The person maintaining your code will be glad you've made the data flow explicit with props. +2. **Extract Components and [pass JSX as `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) to them.** If you pass some data through many layers of intermediate Components that don't use that data (and only pass it further down), this often means that you forgot to extract some Components along the way. For example, maybe you pass data props like `posts` to visual Components that don't use them directly, like `<Layout posts={posts} />`. Instead, make `Layout` take `children` as a prop, and render `<Layout><Posts posts={posts} /></Layout>`. This reduces the number of layers between the Component specifying the data and the one that needs it. If neither of these approaches works well for you, consider context. ## Use cases for context {/*use-cases-for-context*/} -* **Theming:** If your app lets the user change its appearance (e.g. dark mode), you can put a context provider at the top of your app, and use that context in components that need to adjust their visual look. -* **Current account:** Many components might need to know the currently logged in user. Putting it in context makes it convenient to read it anywhere in the tree. Some apps also let you operate multiple accounts at the same time (e.g. to leave a comment as a different user). In those cases, it can be convenient to wrap a part of the UI into a nested provider with a different current account value. +* **Theming:** If your app lets the user change its appearance (e.g. dark mode), you can put a context provider at the top of your app, and use that context in Components that need to adjust their visual look. +* **Current account:** Many Components might need to know the currently logged in user. Putting it in context makes it convenient to read it anywhere in the tree. Some apps also let you operate multiple accounts at the same time (e.g. to leave a comment as a different user). In those cases, it can be convenient to wrap a part of the UI into a nested provider with a different current account value. * **Routing:** Most routing solutions use context internally to hold the current route. This is how every link "knows" whether it's active or not. If you build your own router, you might want to do it too. -* **Managing state:** As your app grows, you might end up with a lot of state closer to the top of your app. Many distant components below may want to change it. It is common to [use a reducer together with context](/learn/scaling-up-with-reducer-and-context) to manage complex state and pass it down to distant components without too much hassle. +* **Managing state:** As your app grows, you might end up with a lot of state closer to the top of your app. Many distant Components below may want to change it. It is common to [use a reducer together with context](/learn/scaling-up-with-reducer-and-context) to manage complex state and pass it down to distant Components without too much hassle. -Context is not limited to static values. If you pass a different value on the next render, React will update all the components reading it below! This is why context is often used in combination with state. +Context is not limited to static values. If you pass a different value on the next render, React will update all the Components reading it below! This is why context is often used in combination with state. -In general, if some information is needed by distant components in different parts of the tree, it's a good indication that context will help you. +In general, if some information is needed by distant Components in different parts of the tree, it's a good indication that context will help you. <Recap> -* Context lets a component provide some information to the entire tree below it. +* Context lets a Component provide some information to the entire tree below it. * To pass context: 1. Create and export it with `export const MyContext = createContext(defaultValue)`. 2. Pass it to the `useContext(MyContext)` Hook to read it in any child component, no matter how deep. 3. Wrap children into `<MyContext.Provider value={...}>` to provide it from a parent. -* Context passes through any components in the middle. -* Context lets you write components that "adapt to their surroundings". +* Context passes through any Components in the middle. +* Context lets you write Components that "adapt to their surroundings". * Before you use context, try passing props or passing JSX as `children`. </Recap> @@ -881,7 +881,7 @@ In general, if some information is needed by distant components in different par In this example, toggling the checkbox changes the `imageSize` prop passed to each `<PlaceImage>`. The checkbox state is held in the top-level `App` component, but each `<PlaceImage>` needs to be aware of it. -Currently, `App` passes `imageSize` to `List`, which passes it to each `Place`, which passes it to the `PlaceImage`. Remove the `imageSize` prop, and instead pass it from the `App` component directly to `PlaceImage`. +Currently, `App` passes `imageSize` to `List`, which passes it to each `Place`, which passes it to the `PlaceImage`. Remove the `imageSize` prop, and instead pass it from the `App` Component directly to `PlaceImage`. You can declare context in `Context.js`. @@ -1157,7 +1157,7 @@ li { </Sandpack> -Note how components in the middle don't need to pass `imageSize` anymore. +Note how Components in the middle don't need to pass `imageSize` anymore. </Solution> diff --git a/src/content/learn/passing-props-to-a-component.md b/src/content/learn/passing-props-to-a-component.md index aae682d14d2..7bc9899f787 100644 --- a/src/content/learn/passing-props-to-a-component.md +++ b/src/content/learn/passing-props-to-a-component.md @@ -4,7 +4,7 @@ title: Passing Props to a Component <Intro> -React components use *props* to communicate with each other. Every parent component can pass some information to its child components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions. +React Components use *props* to communicate with each other. Every parent Component can pass some information to its child Components by giving them props. Props might remind you of HTML attributes, but you can pass any JavaScript value through them, including objects, arrays, and functions. </Intro> @@ -53,9 +53,9 @@ body { min-height: 120px; } The props you can pass to an `<img>` tag are predefined (ReactDOM conforms to [the HTML standard](https://www.w3.org/TR/html52/semantics-embedded-content.html#the-img-element)). But you can pass any props to *your own* components, such as `<Avatar>`, to customize them. Here's how! -## Passing props to a component {/*passing-props-to-a-component*/} +## Passing props to a Component {/*passing-props-to-a-component*/} -In this code, the `Profile` component isn't passing any props to its child component, `Avatar`: +In this code, the `Profile` Component isn't passing any props to its child component, `Avatar`: ```js export default function Profile() { @@ -67,7 +67,7 @@ export default function Profile() { You can give `Avatar` some props in two steps. -### Step 1: Pass props to the child component {/*step-1-pass-props-to-the-child-component*/} +### Step 1: Pass props to the child Component {/*step-1-pass-props-to-the-child-component*/} First, pass some props to `Avatar`. For example, let's pass two props: `person` (an object), and `size` (a number): @@ -90,7 +90,7 @@ If double curly braces after `person=` confuse you, recall [they're merely an ob Now you can read these props inside the `Avatar` component. -### Step 2: Read props inside the child component {/*step-2-read-props-inside-the-child-component*/} +### Step 2: Read props inside the child Component {/*step-2-read-props-inside-the-child-component*/} You can read these props by listing their names `person, size` separated by the commas inside `({` and `})` directly after `function Avatar`. This lets you use them inside the `Avatar` code, like you would with a variable. @@ -168,9 +168,9 @@ body { min-height: 120px; } </Sandpack> -Props let you think about parent and child components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`. +Props let you think about parent and child Components independently. For example, you can change the `person` or the `size` props inside `Profile` without having to think about how `Avatar` uses them. Similarly, you can change how the `Avatar` uses these props, without looking at the `Profile`. -You can think of props like "knobs" that you can adjust. They serve the same role as arguments serve for functions—in fact, props _are_ the only argument to your component! React component functions accept a single argument, a `props` object: +You can think of props like "knobs" that you can adjust. They serve the same role as arguments serve for functions—in fact, props _are_ the only argument to your component! React Component functions accept a single argument, a `props` object: ```js function Avatar(props) { @@ -237,7 +237,7 @@ function Profile({ person, size, isSepia, thickBorder }) { } ``` -There's nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don't use any of their props directly, it can make sense to use a more concise "spread" syntax: +There's nothing wrong with repetitive code—it can be more legible. But at times you may value conciseness. Some Components forward all of their props to their children, like how this `Profile` does with `Avatar`. Because they don't use any of their props directly, it can make sense to use a more concise "spread" syntax: ```js function Profile(props) { @@ -251,7 +251,7 @@ function Profile(props) { This forwards all of `Profile`'s props to the `Avatar` without listing each of their names. -**Use spread syntax with restraint.** If you're using it in every other component, something is wrong. Often, it indicates that you should split your components and pass children as JSX. More on that next! +**Use spread syntax with restraint.** If you're using it in every other component, something is wrong. Often, it indicates that you should split your Components and pass children as JSX. More on that next! ## Passing JSX as children {/*passing-jsx-as-children*/} @@ -263,7 +263,7 @@ It is common to nest built-in browser tags: </div> ``` -Sometimes you'll want to nest your own components the same way: +Sometimes you'll want to nest your own Components the same way: ```js <Card> @@ -271,7 +271,7 @@ Sometimes you'll want to nest your own components the same way: </Card> ``` -When you nest content inside a JSX tag, the parent component will receive that content in a prop called `children`. For example, the `Card` component below will receive a `children` prop set to `<Avatar />` and render it in a wrapper div: +When you nest content inside a JSX tag, the parent Component will receive that content in a prop called `children`. For example, the `Card` Component below will receive a `children` prop set to `<Avatar />` and render it in a wrapper div: <Sandpack> @@ -347,15 +347,15 @@ export function getImageUrl(person, size = 's') { </Sandpack> -Try replacing the `<Avatar>` inside `<Card>` with some text to see how the `Card` component can wrap any nested content. It doesn't need to "know" what's being rendered inside of it. You will see this flexible pattern in many places. +Try replacing the `<Avatar>` inside `<Card>` with some text to see how the `Card` Component can wrap any nested content. It doesn't need to "know" what's being rendered inside of it. You will see this flexible pattern in many places. -You can think of a component with a `children` prop as having a "hole" that can be "filled in" by its parent components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, etc. +You can think of a Component with a `children` prop as having a "hole" that can be "filled in" by its parent Components with arbitrary JSX. You will often use the `children` prop for visual wrappers: panels, grids, etc. <Illustration src="/images/docs/illustrations/i_children-prop.png" alt='A puzzle-like Card tile with a slot for "children" pieces like text and Avatar' /> ## How props change over time {/*how-props-change-over-time*/} -The `Clock` component below receives two props from its parent component: `color` and `time`. (The parent component's code is omitted because it uses [state](/learn/state-a-components-memory), which we won't dive into just yet.) +The `Clock` Component below receives two props from its parent component: `color` and `time`. (The parent component's code is omitted because it uses [state](/learn/state-a-components-memory), which we won't dive into just yet.) Try changing the color in the select box below: @@ -407,9 +407,9 @@ export default function App() { </Sandpack> -This example illustrates that **a component may receive different props over time.** Props are not always static! Here, the `time` prop changes every second, and the `color` prop changes when you select another color. Props reflect a component's data at any point in time, rather than only in the beginning. +This example illustrates that **a Component may receive different props over time.** Props are not always static! Here, the `time` prop changes every second, and the `color` prop changes when you select another color. Props reflect a component's data at any point in time, rather than only in the beginning. -However, props are [immutable](https://en.wikipedia.org/wiki/Immutable_object)—a term from computer science meaning "unchangeable". When a component needs to change its props (for example, in response to a user interaction or new data), it will have to "ask" its parent component to pass it _different props_—a new object! Its old props will then be cast aside, and eventually the JavaScript engine will reclaim the memory taken by them. +However, props are [immutable](https://en.wikipedia.org/wiki/Immutable_object)—a term from computer science meaning "unchangeable". When a Component needs to change its props (for example, in response to a user interaction or new data), it will have to "ask" its parent Component to pass it _different props_—a new object! Its old props will then be cast aside, and eventually the JavaScript engine will reclaim the memory taken by them. **Don't try to "change props".** When you need to respond to the user input (like changing the selected color), you will need to "set state", which you can learn about in [State: A Component's Memory.](/learn/state-a-components-memory) @@ -429,9 +429,9 @@ However, props are [immutable](https://en.wikipedia.org/wiki/Immutable_object) <Challenges> -#### Extract a component {/*extract-a-component*/} +#### Extract a Component {/*extract-a-component*/} -This `Gallery` component contains some very similar markup for two profiles. Extract a `Profile` component out of it to reduce the duplication. You'll need to choose what props to pass to it. +This `Gallery` Component contains some very similar markup for two profiles. Extract a `Profile` Component out of it to reduce the duplication. You'll need to choose what props to pass to it. <Sandpack> @@ -530,7 +530,7 @@ Start by extracting the markup for one of the scientists. Then find the pieces t <Solution> -In this solution, the `Profile` component accepts multiple props: `imageId` (a string), `name` (a string), `profession` (a string), `awards` (an array of strings), `discovery` (a string), and `imageSize` (a number). +In this solution, the `Profile` Component accepts multiple props: `imageId` (a string), `name` (a string), `profession` (a string), `awards` (an array of strings), `discovery` (a string), and `imageSize` (a number). Note that the `imageSize` prop has a default value, which is why we don't pass it to the component. @@ -735,7 +735,7 @@ Although the syntax looks slightly different because you're describing propertie In this example, `Avatar` receives a numeric `size` prop which determines the `<img>` width and height. The `size` prop is set to `40` in this example. However, if you open the image in a new tab, you'll notice that the image itself is larger (`160` pixels). The real image size is determined by which thumbnail size you're requesting. -Change the `Avatar` component to request the closest image size based on the `size` prop. Specifically, if the `size` is less than `90`, pass `'s'` ("small") rather than `'b'` ("big") to the `getImageUrl` function. Verify that your changes work by rendering avatars with different values of the `size` prop and opening images in a new tab. +Change the `Avatar` Component to request the closest image size based on the `size` prop. Specifically, if the `size` is less than `90`, pass `'s'` ("small") rather than `'b'` ("big") to the `getImageUrl` function. Verify that your changes work by rendering avatars with different values of the `size` prop and opening images in a new tab. <Sandpack> @@ -919,13 +919,13 @@ export function getImageUrl(person, size) { </Sandpack> -Props let you encapsulate logic like this inside the `Avatar` component (and change it later if needed) so that everyone can use the `<Avatar>` component without thinking about how the images are requested and resized. +Props let you encapsulate logic like this inside the `Avatar` Component (and change it later if needed) so that everyone can use the `<Avatar>` Component without thinking about how the images are requested and resized. </Solution> #### Passing JSX in a `children` prop {/*passing-jsx-in-a-children-prop*/} -Extract a `Card` component from the markup below, and use the `children` prop to pass different JSX to it: +Extract a `Card` Component from the markup below, and use the `children` prop to pass different JSX to it: <Sandpack> @@ -989,7 +989,7 @@ Any JSX you put inside of a component's tag will be passed as the `children` pro <Solution> -This is how you can use the `Card` component in both places: +This is how you can use the `Card` Component in both places: <Sandpack> diff --git a/src/content/learn/preserving-and-resetting-state.md b/src/content/learn/preserving-and-resetting-state.md index d35071845d2..033ebeba633 100644 --- a/src/content/learn/preserving-and-resetting-state.md +++ b/src/content/learn/preserving-and-resetting-state.md @@ -4,7 +4,7 @@ title: Preserving and Resetting State <Intro> -State is isolated between components. React keeps track of which state belongs to which component based on their place in the UI tree. You can control when to preserve state and when to reset it between re-renders. +State is isolated between components. React keeps track of which state belongs to which Component based on their place in the UI tree. You can control when to preserve state and when to reset it between re-renders. </Intro> @@ -18,9 +18,9 @@ State is isolated between components. React keeps track of which state belongs t ## State is tied to a position in the render tree {/*state-is-tied-to-a-position-in-the-tree*/} -React builds [render trees](learn/understanding-your-ui-as-a-tree#the-render-tree) for the component structure in your UI. +React builds [render trees](learn/understanding-your-ui-as-a-tree#the-render-tree) for the Component structure in your UI. -When you give a component state, you might think the state "lives" inside the component. But the state is actually held inside React. React associates each piece of state it's holding with the correct component by where that component sits in the render tree. +When you give a Component state, you might think the state "lives" inside the component. But the state is actually held inside React. React associates each piece of state it's holding with the correct Component by where that Component sits in the render tree. Here, there is only one `<Counter />` JSX tag, but it's rendered at two different positions: @@ -100,7 +100,7 @@ React tree **These are two separate counters because each is rendered at its own position in the tree.** You don't usually have to think about these positions to use React, but it can be useful to understand how it works. -In React, each component on the screen has fully isolated state. For example, if you render two `Counter` components side by side, each of them will get its own, independent, `score` and `hover` states. +In React, each Component on the screen has fully isolated state. For example, if you render two `Counter` Components side by side, each of them will get its own, independent, `score` and `hover` states. Try clicking both counters and notice they don't affect each other: @@ -160,7 +160,7 @@ function Counter() { </Sandpack> -As you can see, when one counter is updated, only the state for that component is updated: +As you can see, when one counter is updated, only the state for that Component is updated: <DiagramGroup> @@ -174,7 +174,7 @@ Updating state </DiagramGroup> -React will keep the state around for as long as you render the same component at the same position in the tree. To see this, increment both counters, then remove the second component by unchecking "Render the second counter" checkbox, and then add it back by ticking it again: +React will keep the state around for as long as you render the same Component at the same position in the tree. To see this, increment both counters, then remove the second Component by unchecking "Render the second counter" checkbox, and then add it back by ticking it again: <Sandpack> @@ -252,7 +252,7 @@ Notice how the moment you stop rendering the second counter, its state disappear <DiagramGroup> -<Diagram name="preserving_state_remove_component" height={253} width={422} alt="Diagram of a tree of React components. The root node is labeled 'div' and has two children. The left child is labeled 'Counter' and contains a state bubble labeled 'count' with value 0. The right child is missing, and in its place is a yellow 'poof' image, highlighting the component being deleted from the tree."> +<Diagram name="preserving_state_remove_component" height={253} width={422} alt="Diagram of a tree of React components. The root node is labeled 'div' and has two children. The left child is labeled 'Counter' and contains a state bubble labeled 'count' with value 0. The right child is missing, and in its place is a yellow 'poof' image, highlighting the Component being deleted from the tree."> Deleting a component @@ -272,9 +272,9 @@ Adding a component </DiagramGroup> -**React preserves a component's state for as long as it's being rendered at its position in the UI tree.** If it gets removed, or a different component gets rendered at the same position, React discards its state. +**React preserves a component's state for as long as it's being rendered at its position in the UI tree.** If it gets removed, or a different Component gets rendered at the same position, React discards its state. -## Same component at the same position preserves state {/*same-component-at-the-same-position-preserves-state*/} +## Same Component at the same position preserves state {/*same-component-at-the-same-position-preserves-state*/} In this example, there are two different `<Counter />` tags: @@ -365,7 +365,7 @@ When you tick or clear the checkbox, the counter state does not get reset. Wheth <DiagramGroup> -<Diagram name="preserving_state_same_component" height={461} width={600} alt="Diagram with two sections separated by an arrow transitioning between them. Each section contains a layout of components with a parent labeled 'App' containing a state bubble labeled isFancy. This component has one child labeled 'div', which leads to a prop bubble containing isFancy (highlighted in purple) passed down to the only child. The last child is labeled 'Counter' and contains a state bubble with label 'count' and value 3 in both diagrams. In the left section of the diagram, nothing is highlighted and the isFancy parent state value is false. In the right section of the diagram, the isFancy parent state value has changed to true and it is highlighted in yellow, and so is the props bubble below, which has also changed its isFancy value to true."> +<Diagram name="preserving_state_same_component" height={461} width={600} alt="Diagram with two sections separated by an arrow transitioning between them. Each section contains a layout of Components with a parent labeled 'App' containing a state bubble labeled isFancy. This Component has one child labeled 'div', which leads to a prop bubble containing isFancy (highlighted in purple) passed down to the only child. The last child is labeled 'Counter' and contains a state bubble with label 'count' and value 3 in both diagrams. In the left section of the diagram, nothing is highlighted and the isFancy parent state value is false. In the right section of the diagram, the isFancy parent state value has changed to true and it is highlighted in yellow, and so is the props bubble below, which has also changed its isFancy value to true."> Updating the `App` state does not reset the `Counter` because `Counter` stays in the same position @@ -374,11 +374,11 @@ Updating the `App` state does not reset the `Counter` because `Counter` stays in </DiagramGroup> -It's the same component at the same position, so from React's perspective, it's the same counter. +It's the same Component at the same position, so from React's perspective, it's the same counter. <Pitfall> -Remember that **it's the position in the UI tree--not in the JSX markup--that matters to React!** This component has two `return` clauses with different `<Counter />` JSX tags inside and outside the `if`: +Remember that **it's the position in the UI tree--not in the JSX markup--that matters to React!** This Component has two `return` clauses with different `<Counter />` JSX tags inside and outside the `if`: <Sandpack> @@ -478,11 +478,11 @@ label { You might expect the state to reset when you tick checkbox, but it doesn't! This is because **both of these `<Counter />` tags are rendered at the same position.** React doesn't know where you place the conditions in your function. All it "sees" is the tree you return. -In both cases, the `App` component returns a `<div>` with `<Counter />` as a first child. To React, these two counters have the same "address": the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic. +In both cases, the `App` Component returns a `<div>` with `<Counter />` as a first child. To React, these two counters have the same "address": the first child of the first child of the root. This is how React matches them up between the previous and next renders, regardless of how you structure your logic. </Pitfall> -## Different components at the same position reset state {/*different-components-at-the-same-position-reset-state*/} +## Different Components at the same position reset state {/*different-components-at-the-same-position-reset-state*/} In this example, ticking the checkbox will replace `<Counter>` with a `<p>`: @@ -561,11 +561,11 @@ label { </Sandpack> -Here, you switch between _different_ component types at the same position. Initially, the first child of the `<div>` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state. +Here, you switch between _different_ Component types at the same position. Initially, the first child of the `<div>` contained a `Counter`. But when you swapped in a `p`, React removed the `Counter` from the UI tree and destroyed its state. <DiagramGroup> -<Diagram name="preserving_state_diff_pt1" height={290} width={753} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React component labeled 'div' with a single child labeled 'Counter' containing a state bubble labeled 'count' with value 3. The middle section has the same 'div' parent, but the child component has now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'p', highlighted in yellow."> +<Diagram name="preserving_state_diff_pt1" height={290} width={753} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React Component labeled 'div' with a single child labeled 'Counter' containing a state bubble labeled 'count' with value 3. The middle section has the same 'div' parent, but the child Component has now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'p', highlighted in yellow."> When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added @@ -575,7 +575,7 @@ When `Counter` changes to `p`, the `Counter` is deleted and the `p` is added <DiagramGroup> -<Diagram name="preserving_state_diff_pt2" height={290} width={753} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React component labeled 'p'. The middle section has the same 'div' parent, but the child component has now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, highlighted in yellow."> +<Diagram name="preserving_state_diff_pt2" height={290} width={753} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React Component labeled 'p'. The middle section has the same 'div' parent, but the child Component has now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, highlighted in yellow."> When switching back, the `p` is deleted and the `Counter` is added @@ -583,7 +583,7 @@ When switching back, the `p` is deleted and the `Counter` is added </DiagramGroup> -Also, **when you render a different component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox: +Also, **when you render a different Component in the same position, it resets the state of its entire subtree.** To see how this works, increment the counter and then tick the checkbox: <Sandpack> @@ -676,7 +676,7 @@ The counter state gets reset when you click the checkbox. Although you render a <DiagramGroup> -<Diagram name="preserving_state_diff_same_pt1" height={350} width={794} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React component labeled 'div' with a single child labeled 'section', which has a single child labeled 'Counter' containing a state bubble labeled 'count' with value 3. The middle section has the same 'div' parent, but the child components have now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'div', highlighted in yellow, also with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, all highlighted in yellow."> +<Diagram name="preserving_state_diff_same_pt1" height={350} width={794} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React Component labeled 'div' with a single child labeled 'section', which has a single child labeled 'Counter' containing a state bubble labeled 'count' with value 3. The middle section has the same 'div' parent, but the child Components have now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'div', highlighted in yellow, also with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, all highlighted in yellow."> When `section` changes to `div`, the `section` is deleted and the new `div` is added @@ -686,7 +686,7 @@ When `section` changes to `div`, the `section` is deleted and the new `div` is a <DiagramGroup> -<Diagram name="preserving_state_diff_same_pt2" height={350} width={794} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React component labeled 'div' with a single child labeled 'div', which has a single child labeled 'Counter' containing a state bubble labeled 'count' with value 0. The middle section has the same 'div' parent, but the child components have now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'section', highlighted in yellow, also with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, all highlighted in yellow."> +<Diagram name="preserving_state_diff_same_pt2" height={350} width={794} alt="Diagram with three sections, with an arrow transitioning each section in between. The first section contains a React Component labeled 'div' with a single child labeled 'div', which has a single child labeled 'Counter' containing a state bubble labeled 'count' with value 0. The middle section has the same 'div' parent, but the child Components have now been deleted, indicated by a yellow 'proof' image. The third section has the same 'div' parent again, now with a new child labeled 'section', highlighted in yellow, also with a new child labeled 'Counter' containing a state bubble labeled 'count' with value 0, all highlighted in yellow."> When switching back, the `div` is deleted and the new `section` is added @@ -694,13 +694,13 @@ When switching back, the `div` is deleted and the new `section` is added </DiagramGroup> -As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to "match up"** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a component from the tree. +As a rule of thumb, **if you want to preserve the state between re-renders, the structure of your tree needs to "match up"** from one render to another. If the structure is different, the state gets destroyed because React destroys state when it removes a Component from the tree. <Pitfall> -This is why you should not nest component function definitions. +This is why you should not nest Component function definitions. -Here, the `MyTextField` component function is defined *inside* `MyComponent`: +Here, the `MyTextField` Component function is defined *inside* `MyComponent`: <Sandpack> @@ -735,13 +735,13 @@ export default function MyComponent() { </Sandpack> -Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You're rendering a *different* component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare component functions at the top level, and don't nest their definitions.** +Every time you click the button, the input state disappears! This is because a *different* `MyTextField` function is created for every render of `MyComponent`. You're rendering a *different* Component in the same position, so React resets all state below. This leads to bugs and performance problems. To avoid this problem, **always declare Component functions at the top level, and don't nest their definitions.** </Pitfall> ## Resetting state at the same position {/*resetting-state-at-the-same-position*/} -By default, React preserves state of a component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component's state. Consider this app that lets two players keep track of their scores during each turn: +By default, React preserves state of a Component while it stays at the same position. Usually, this is exactly what you want, so it makes sense as the default behavior. But sometimes, you may want to reset a component's state. Consider this app that lets two players keep track of their scores during each turn: <Sandpack> @@ -817,11 +817,11 @@ But conceptually, in this app they should be two separate counters. They might a There are two ways to reset state when switching between them: -1. Render components in different positions -2. Give each component an explicit identity with `key` +1. Render Components in different positions +2. Give each Component an explicit identity with `key` -### Option 1: Rendering a component in different positions {/*option-1-rendering-a-component-in-different-positions*/} +### Option 1: Rendering a Component in different positions {/*option-1-rendering-a-component-in-different-positions*/} If you want these two `Counter`s to be independent, you can render them in two different positions: @@ -921,7 +921,7 @@ Clicking "next" again Each `Counter`'s state gets destroyed each time it's removed from the DOM. This is why they reset every time you click the button. -This solution is convenient when you only have a few independent components rendered in the same place. In this example, you only have two, so it's not a hassle to render both separately in the JSX. +This solution is convenient when you only have a few independent Components rendered in the same place. In this example, you only have two, so it's not a hassle to render both separately in the JSX. ### Option 2: Resetting state with a key {/*option-2-resetting-state-with-a-key*/} @@ -1021,7 +1021,7 @@ Remember that keys are not globally unique. They only specify the position *with Resetting state with a key is particularly useful when dealing with forms. -In this chat app, the `<Chat>` component contains the text input state: +In this chat app, the `<Chat>` Component contains the text input state: <Sandpack> @@ -1124,7 +1124,7 @@ Try entering something into the input, and then press "Alice" or "Bob" to choose <Chat key={to.id} contact={to} /> ``` -This ensures that when you select a different recipient, the `Chat` component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them. +This ensures that when you select a different recipient, the `Chat` Component will be recreated from scratch, including any state in the tree below it. React will also re-create the DOM elements instead of reusing them. Now switching the recipient always clears the text field: @@ -1223,13 +1223,13 @@ textarea { <DeepDive> -#### Preserving state for removed components {/*preserving-state-for-removed-components*/} +#### Preserving state for removed Components {/*preserving-state-for-removed-components*/} -In a real chat app, you'd probably want to recover the input state when the user selects the previous recipient again. There are a few ways to keep the state "alive" for a component that's no longer visible: +In a real chat app, you'd probably want to recover the input state when the user selects the previous recipient again. There are a few ways to keep the state "alive" for a Component that's no longer visible: - You could render _all_ chats instead of just the current one, but hide all the others with CSS. The chats would not get removed from the tree, so their local state would be preserved. This solution works great for simple UIs. But it can get very slow if the hidden trees are large and contain a lot of DOM nodes. -- You could [lift the state up](/learn/sharing-state-between-components) and hold the pending message for each recipient in the parent component. This way, when the child components get removed, it doesn't matter, because it's the parent that keeps the important information. This is the most common solution. -- You might also use a different source in addition to React state. For example, you probably want a message draft to persist even if the user accidentally closes the page. To implement this, you could have the `Chat` component initialize its state by reading from the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), and save the drafts there too. +- You could [lift the state up](/learn/sharing-state-between-components) and hold the pending message for each recipient in the parent component. This way, when the child Components get removed, it doesn't matter, because it's the parent that keeps the important information. This is the most common solution. +- You might also use a different source in addition to React state. For example, you probably want a message draft to persist even if the user accidentally closes the page. To implement this, you could have the `Chat` Component initialize its state by reading from the [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage), and save the drafts there too. No matter which strategy you pick, a chat _with Alice_ is conceptually distinct from a chat _with Bob_, so it makes sense to give a `key` to the `<Chat>` tree based on the current recipient. @@ -1237,10 +1237,10 @@ No matter which strategy you pick, a chat _with Alice_ is conceptually distinct <Recap> -- React keeps state for as long as the same component is rendered at the same position. +- React keeps state for as long as the same Component is rendered at the same position. - State is not kept in JSX tags. It's associated with the tree position in which you put that JSX. - You can force a subtree to reset its state by giving it a different key. -- Don't nest component definitions, or you'll reset state by accident. +- Don't nest Component definitions, or you'll reset state by accident. </Recap> @@ -1299,7 +1299,7 @@ textarea { display: block; margin: 10px 0; } <Solution> -The problem is that `Form` is rendered in different positions. In the `if` branch, it is the second child of the `<div>`, but in the `else` branch, it is the first child. Therefore, the component type in each position changes. The first position changes between holding a `p` and a `Form`, while the second position changes between holding a `Form` and a `button`. React resets the state every time the component type changes. +The problem is that `Form` is rendered in different positions. In the `if` branch, it is the second child of the `<div>`, but in the `else` branch, it is the first child. Therefore, the Component type in each position changes. The first position changes between holding a `p` and a `Form`, while the second position changes between holding a `Form` and a `button`. React resets the state every time the Component type changes. The easiest solution is to unify the branches so that `Form` always renders in the same position: @@ -1471,7 +1471,7 @@ label { display: block; margin: 10px 0; } <Solution> -Give a `key` to both `<Field>` components in both `if` and `else` branches. This tells React how to "match up" the correct state for either `<Field>` even if their order within the parent changes: +Give a `key` to both `<Field>` Components in both `if` and `else` branches. This tells React how to "match up" the correct state for either `<Field>` even if their order within the parent changes: <Sandpack> diff --git a/src/content/learn/reacting-to-input-with-state.md b/src/content/learn/reacting-to-input-with-state.md index da559dc0fac..6d9329316fe 100644 --- a/src/content/learn/reacting-to-input-with-state.md +++ b/src/content/learn/reacting-to-input-with-state.md @@ -4,14 +4,14 @@ title: Reacting to Input with State <Intro> -React provides a declarative way to manipulate the UI. Instead of manipulating individual pieces of the UI directly, you describe the different states that your component can be in, and switch between them in response to the user input. This is similar to how designers think about the UI. +React provides a declarative way to manipulate the UI. Instead of manipulating individual pieces of the UI directly, you describe the different states that your Component can be in, and switch between them in response to the user input. This is similar to how designers think about the UI. </Intro> <YouWillLearn> * How declarative UI programming differs from imperative UI programming -* How to enumerate the different visual states your component can be in +* How to enumerate the different visual states your Component can be in * How to trigger the changes between the different visual states from code </YouWillLearn> @@ -135,7 +135,7 @@ Manipulating the UI imperatively works well enough for isolated examples, but it React was built to solve this problem. -In React, you don't directly manipulate the UI--meaning you don't enable, disable, show, or hide components directly. Instead, you **declare what you want to show,** and React figures out how to update the UI. Think of getting into a taxi and telling the driver where you want to go instead of telling them exactly where to turn. It's the driver's job to get you there, and they might even know some shortcuts you haven't considered! +In React, you don't directly manipulate the UI--meaning you don't enable, disable, show, or hide Components directly. Instead, you **declare what you want to show,** and React figures out how to update the UI. Think of getting into a taxi and telling the driver where you want to go instead of telling them exactly where to turn. It's the driver's job to get you there, and they might even know some shortcuts you haven't considered! <Illustration src="/images/docs/illustrations/i_declarative-ui-programming.png" alt="In a car driven by React, a passenger asks to be taken to a specific place on the map. React figures out how to do that." /> @@ -242,7 +242,7 @@ export default function Form({ #### Displaying many visual states at once {/*displaying-many-visual-states-at-once*/} -If a component has a lot of visual states, it can be convenient to show them all on one page: +If a Component has a lot of visual states, it can be convenient to show them all on one page: <Sandpack> @@ -350,7 +350,7 @@ Form states ### Step 3: Represent the state in memory with `useState` {/*step-3-represent-the-state-in-memory-with-usestate*/} -Next you'll need to represent the visual states of your component in memory with [`useState`.](/reference/react/useState) Simplicity is key: each piece of state is a "moving piece", and **you want as few "moving pieces" as possible.** More complexity leads to more bugs! +Next you'll need to represent the visual states of your Component in memory with [`useState`.](/reference/react/useState) Simplicity is key: each piece of state is a "moving piece", and **you want as few "moving pieces" as possible.** More complexity leads to more bugs! Start with the state that *absolutely must* be there. For example, you'll need to store the `answer` for the input, and the `error` (if it exists) to store the last error: @@ -375,7 +375,7 @@ Your first idea likely won't be the best, but that's ok--refactoring state is a ### Step 4: Remove any non-essential state variables {/*step-4-remove-any-non-essential-state-variables*/} -You want to avoid duplication in the state content so you're only tracking what is essential. Spending a little time on refactoring your state structure will make your components easier to understand, reduce duplication, and avoid unintended meanings. Your goal is to **prevent the cases where the state in memory doesn't represent any valid UI that you'd want a user to see.** (For example, you never want to show an error message and disable the input at the same time, or the user won't be able to correct the error!) +You want to avoid duplication in the state content so you're only tracking what is essential. Spending a little time on refactoring your state structure will make your Components easier to understand, reduce duplication, and avoid unintended meanings. Your goal is to **prevent the cases where the state in memory doesn't represent any valid UI that you'd want a user to see.** (For example, you never want to show an error message and disable the input at the same time, or the user won't be able to correct the error!) Here are some questions you can ask about your state variables: @@ -557,7 +557,7 @@ body { margin: 0; padding: 0; height: 250px; } <Solution> -This component has two visual states: when the image is active, and when the image is inactive: +This Component has two visual states: when the image is active, and when the image is inactive: * When the image is active, the CSS classes are `background` and `picture picture--active`. * When the image is inactive, the CSS classes are `background background--active` and `picture`. diff --git a/src/content/learn/referencing-values-with-refs.md b/src/content/learn/referencing-values-with-refs.md index 4faf18786f6..8423e45ad8f 100644 --- a/src/content/learn/referencing-values-with-refs.md +++ b/src/content/learn/referencing-values-with-refs.md @@ -4,7 +4,7 @@ title: 'Referencing Values with Refs' <Intro> -When you want a component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*. +When you want a Component to "remember" some information, but you don't want that information to [trigger new renders](/learn/render-and-commit), you can use a *ref*. </Intro> @@ -17,9 +17,9 @@ When you want a component to "remember" some information, but you don't want tha </YouWillLearn> -## Adding a ref to your component {/*adding-a-ref-to-your-component*/} +## Adding a ref to your Component {/*adding-a-ref-to-your-component*/} -You can add a ref to your component by importing the `useRef` Hook from React: +You can add a ref to your Component by importing the `useRef` Hook from React: ```js import { useRef } from 'react'; @@ -41,7 +41,7 @@ const ref = useRef(0); <Illustration src="/images/docs/illustrations/i_ref.png" alt="An arrow with 'current' written on it stuffed into a pocket with 'ref' written on it." /> -You can access the current value of that ref through the `ref.current` property. This value is intentionally mutable, meaning you can both read and write to it. It's like a secret pocket of your component that React doesn't track. (This is what makes it an "escape hatch" from React's one-way data flow--more on that below!) +You can access the current value of that ref through the `ref.current` property. This value is intentionally mutable, meaning you can both read and write to it. It's like a secret pocket of your Component that React doesn't track. (This is what makes it an "escape hatch" from React's one-way data flow--more on that below!) Here, a button will increment `ref.current` on every click: @@ -70,7 +70,7 @@ export default function Counter() { The ref points to a number, but, like [state](/learn/state-a-components-memory), you could point to anything: a string, an object, or even a function. Unlike state, ref is a plain JavaScript object with the `current` property that you can read and modify. -Note that **the component doesn't re-render with every increment.** Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! +Note that **the Component doesn't re-render with every increment.** Like state, refs are retained by React between re-renders. However, setting state re-renders a component. Changing a ref does not! ## Example: building a stopwatch {/*example-building-a-stopwatch*/} @@ -205,7 +205,7 @@ export default function Counter() { </Sandpack> -Because the `count` value is displayed, it makes sense to use a state value for it. When the counter's value is set with `setCount()`, React re-renders the component and the screen updates to reflect the new count. +Because the `count` value is displayed, it makes sense to use a state value for it. When the counter's value is set with `setCount()`, React re-renders the Component and the screen updates to reflect the new count. If you tried to implement this with a ref, React would never re-render the component, so you'd never see the count change! See how clicking this button **does not update its text**: @@ -256,17 +256,17 @@ React provides a built-in version of `useRef` because it is common enough in pra ## When to use refs {/*when-to-use-refs*/} -Typically, you will use a ref when your component needs to "step outside" React and communicate with external APIs—often a browser API that won't impact the appearance of the component. Here are a few of these rare situations: +Typically, you will use a ref when your Component needs to "step outside" React and communicate with external APIs—often a browser API that won't impact the appearance of the component. Here are a few of these rare situations: - Storing [timeout IDs](https://developer.mozilla.org/docs/Web/API/setTimeout) - Storing and manipulating [DOM elements](https://developer.mozilla.org/docs/Web/API/Element), which we cover on [the next page](/learn/manipulating-the-dom-with-refs) - Storing other objects that aren't necessary to calculate the JSX. -If your component needs to store some value, but it doesn't impact the rendering logic, choose refs. +If your Component needs to store some value, but it doesn't impact the rendering logic, choose refs. ## Best practices for refs {/*best-practices-for-refs*/} -Following these principles will make your components more predictable: +Following these principles will make your Components more predictable: - **Treat refs as an escape hatch.** Refs are useful when you work with external systems or browser APIs. If much of your application logic and data flow relies on refs, you might want to rethink your approach. - **Don't read or write `ref.current` during rendering.** If some information is needed during rendering, use [state](/learn/state-a-components-memory) instead. Since React doesn't know when `ref.current` changes, even reading it while rendering makes your component's behavior difficult to predict. (The only exception to this is code like `if (!ref.current) ref.current = new Thing()` which only sets the ref once during the first render.) @@ -293,7 +293,7 @@ You can point a ref to any value. However, the most common use case for a ref is - You can ask React to give you a ref by calling the `useRef` Hook. - Like state, refs let you retain information between re-renders of a component. - Unlike state, setting the ref's `current` value does not trigger a re-render. -- Don't read or write `ref.current` during rendering. This makes your component hard to predict. +- Don't read or write `ref.current` during rendering. This makes your Component hard to predict. </Recap> @@ -307,7 +307,7 @@ Type a message and click "Send". You will notice there is a three second delay b <Hint> -Regular variables like `let timeoutID` don't "survive" between re-renders because every render runs your component (and initializes its variables) from scratch. Should you keep the timeout ID somewhere else? +Regular variables like `let timeoutID` don't "survive" between re-renders because every render runs your Component (and initializes its variables) from scratch. Should you keep the timeout ID somewhere else? </Hint> @@ -360,7 +360,7 @@ export default function Chat() { <Solution> -Whenever your component re-renders (such as when you set state), all local variables get initialized from scratch. This is why you can't save the timeout ID in a local variable like `timeoutID` and then expect another event handler to "see" it in the future. Instead, store it in a ref, which React will preserve between renders. +Whenever your Component re-renders (such as when you set state), all local variables get initialized from scratch. This is why you can't save the timeout ID in a local variable like `timeoutID` and then expect another event handler to "see" it in the future. Instead, store it in a ref, which React will preserve between renders. <Sandpack> @@ -412,7 +412,7 @@ export default function Chat() { </Solution> -#### Fix a component failing to re-render {/*fix-a-component-failing-to-re-render*/} +#### Fix a Component failing to re-render {/*fix-a-component-failing-to-re-render*/} This button is supposed to toggle between showing "On" and "Off". However, it always shows "Off". What is wrong with this code? Fix it. diff --git a/src/content/learn/removing-effect-dependencies.md b/src/content/learn/removing-effect-dependencies.md index 9a871c6c3f0..769b28fb584 100644 --- a/src/content/learn/removing-effect-dependencies.md +++ b/src/content/learn/removing-effect-dependencies.md @@ -205,7 +205,7 @@ function ChatRoom({ roomId }) { And the linter would be right! Since `roomId` may change over time, this would introduce a bug in your code. -**To remove a dependency, "prove" to the linter that it *doesn't need* to be a dependency.** For example, you can move `roomId` out of your component to prove that it's not reactive and won't change on re-renders: +**To remove a dependency, "prove" to the linter that it *doesn't need* to be a dependency.** For example, you can move `roomId` out of your Component to prove that it's not reactive and won't change on re-renders: ```js {2,9} const serverUrl = 'https://localhost:1234'; @@ -394,7 +394,7 @@ function Form() { } ``` -Later, you want to style the notification message according to the current theme, so you read the current theme. Since `theme` is declared in the component body, it is a reactive value, so you add it as a dependency: +Later, you want to style the notification message according to the current theme, so you read the current theme. Since `theme` is declared in the Component body, it is a reactive value, so you add it as a dependency: ```js {3,9,11} function Form() { @@ -587,7 +587,7 @@ function ChatRoom({ roomId }) { And making `messages` a dependency introduces a problem. -Every time you receive a message, `setMessages()` causes the component to re-render with a new `messages` array that includes the received message. However, since this Effect now depends on `messages`, this will *also* re-synchronize the Effect. So every new message will make the chat re-connect. The user would not like that! +Every time you receive a message, `setMessages()` causes the Component to re-render with a new `messages` array that includes the received message. However, since this Effect now depends on `messages`, this will *also* re-synchronize the Effect. So every new message will make the chat re-connect. The user would not like that! To fix the issue, don't read `messages` inside the Effect. Instead, pass an [updater function](/reference/react/useState#updating-state-based-on-the-previous-state) to `setMessages`: @@ -688,7 +688,7 @@ Effect Events let you split an Effect into reactive parts (which should "react" #### Wrapping an event handler from the props {/*wrapping-an-event-handler-from-the-props*/} -You might run into a similar problem when your component receives an event handler as a prop: +You might run into a similar problem when your Component receives an event handler as a prop: ```js {1,8,11} function ChatRoom({ roomId, onReceiveMessage }) { @@ -705,7 +705,7 @@ function ChatRoom({ roomId, onReceiveMessage }) { // ... ``` -Suppose that the parent component passes a *different* `onReceiveMessage` function on every render: +Suppose that the parent Component passes a *different* `onReceiveMessage` function on every render: ```js {3-5} <ChatRoom @@ -737,7 +737,7 @@ function ChatRoom({ roomId, onReceiveMessage }) { // ... ``` -Effect Events aren't reactive, so you don't need to specify them as dependencies. As a result, the chat will no longer re-connect even if the parent component passes a function that's different on every re-render. +Effect Events aren't reactive, so you don't need to specify them as dependencies. As a result, the chat will no longer re-connect even if the parent Component passes a function that's different on every re-render. #### Separating reactive and non-reactive code {/*separating-reactive-and-non-reactive-code*/} @@ -778,7 +778,7 @@ function ChatRoom({ roomId }) { // ... ``` -This object is declared in the component body, so it's a [reactive value.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) When you read a reactive value like this inside an Effect, you declare it as a dependency. This ensures your Effect "reacts" to its changes: +This object is declared in the Component body, so it's a [reactive value.](/learn/lifecycle-of-reactive-effects#effects-react-to-reactive-values) When you read a reactive value like this inside an Effect, you declare it as a dependency. This ensures your Effect "reacts" to its changes: ```js {3,6} // ... @@ -867,7 +867,7 @@ button { margin-left: 10px; } </Sandpack> -In the sandbox above, the input only updates the `message` state variable. From the user's perspective, this should not affect the chat connection. However, every time you update the `message`, your component re-renders. When your component re-renders, the code inside of it runs again from scratch. +In the sandbox above, the input only updates the `message` state variable. From the user's perspective, this should not affect the chat connection. However, every time you update the `message`, your Component re-renders. When your Component re-renders, the code inside of it runs again from scratch. A new `options` object is created from scratch on every re-render of the `ChatRoom` component. React sees that the `options` object is a *different object* from the `options` object created during the last render. This is why it re-synchronizes your Effect (which depends on `options`), and the chat re-connects as you type. @@ -888,7 +888,7 @@ console.log(Object.is(options1, options2)); // false This is why, whenever possible, you should try to avoid objects and functions as your Effect's dependencies. Instead, try moving them outside the component, inside the Effect, or extracting primitive values out of them. -#### Move static objects and functions outside your component {/*move-static-objects-and-functions-outside-your-component*/} +#### Move static objects and functions outside your Component {/*move-static-objects-and-functions-outside-your-component*/} If the object does not depend on any props and state, you can move that object outside your component: @@ -1088,7 +1088,7 @@ function ChatRoom({ options }) { // ... ``` -The risk here is that the parent component will create the object during rendering: +The risk here is that the parent Component will create the object during rendering: ```js {3-6} <ChatRoom @@ -1100,7 +1100,7 @@ The risk here is that the parent component will create the object during renderi /> ``` -This would cause your Effect to re-connect every time the parent component re-renders. To fix this, read information from the object *outside* the Effect, and avoid having object and function dependencies: +This would cause your Effect to re-connect every time the parent Component re-renders. To fix this, read information from the object *outside* the Effect, and avoid having object and function dependencies: ```js {4,7-8,12} function ChatRoom({ options }) { @@ -1122,7 +1122,7 @@ The logic gets a little repetitive (you read some values from an object outside #### Calculate primitive values from functions {/*calculate-primitive-values-from-functions*/} -The same approach can work for functions. For example, suppose the parent component passes a function: +The same approach can work for functions. For example, suppose the parent Component passes a function: ```js {3-8} <ChatRoom @@ -1167,7 +1167,7 @@ This only works for [pure](/learn/keeping-components-pure) functions because the - If you want to update some state based on the previous state, pass an updater function. - If you want to read the latest value without "reacting" it, extract an Effect Event from your Effect. - In JavaScript, objects and functions are considered different if they were created at different times. -- Try to avoid object and function dependencies. Move them outside the component or inside the Effect. +- Try to avoid object and function dependencies. Move them outside the Component or inside the Effect. </Recap> @@ -1798,7 +1798,7 @@ label, button { display: block; margin-bottom: 5px; } </Sandpack> -Sticking to primitive props where possible makes it easier to optimize your components later. +Sticking to primitive props where possible makes it easier to optimize your Components later. </Solution> diff --git a/src/content/learn/render-and-commit.md b/src/content/learn/render-and-commit.md index 3f05935992c..66bb50ec3b9 100644 --- a/src/content/learn/render-and-commit.md +++ b/src/content/learn/render-and-commit.md @@ -4,7 +4,7 @@ title: Render and Commit <Intro> -Before your components are displayed on screen, they must be rendered by React. Understanding the steps in this process will help you think about how your code executes and explain its behavior. +Before your Components are displayed on screen, they must be rendered by React. Understanding the steps in this process will help you think about how your code executes and explain its behavior. </Intro> @@ -12,15 +12,15 @@ Before your components are displayed on screen, they must be rendered by React. * What rendering means in React * When and why React renders a component -* The steps involved in displaying a component on screen +* The steps involved in displaying a Component on screen * Why rendering does not always produce a DOM update </YouWillLearn> -Imagine that your components are cooks in the kitchen, assembling tasty dishes from ingredients. In this scenario, React is the waiter who puts in requests from customers and brings them their orders. This process of requesting and serving UI has three steps: +Imagine that your Components are cooks in the kitchen, assembling tasty dishes from ingredients. In this scenario, React is the waiter who puts in requests from customers and brings them their orders. This process of requesting and serving UI has three steps: 1. **Triggering** a render (delivering the guest's order to the kitchen) -2. **Rendering** the component (preparing the order in the kitchen) +2. **Rendering** the Component (preparing the order in the kitchen) 3. **Committing** to the DOM (placing the order on the table) <IllustrationBlock sequential> @@ -31,7 +31,7 @@ Imagine that your components are cooks in the kitchen, assembling tasty dishes f ## Step 1: Trigger a render {/*step-1-trigger-a-render*/} -There are two reasons for a component to render: +There are two reasons for a Component to render: 1. It's the component's **initial render.** 2. The component's (or one of its ancestors') **state has been updated.** @@ -63,11 +63,11 @@ export default function Image() { </Sandpack> -Try commenting out the `root.render()` call and see the component disappear! +Try commenting out the `root.render()` call and see the Component disappear! ### Re-renders when state updates {/*re-renders-when-state-updates*/} -Once the component has been initially rendered, you can trigger further renders by updating its state with the [`set` function.](/reference/react/useState#setstate) Updating your component's state automatically queues a render. (You can imagine these as a restaurant guest ordering tea, dessert, and all sorts of things after putting in their first order, depending on the state of their thirst or hunger.) +Once the Component has been initially rendered, you can trigger further renders by updating its state with the [`set` function.](/reference/react/useState#setstate) Updating your component's state automatically queues a render. (You can imagine these as a restaurant guest ordering tea, dessert, and all sorts of things after putting in their first order, depending on the state of their thirst or hunger.) <IllustrationBlock sequential> <Illustration caption="State update..." alt="React as a server in a restaurant, serving a Card UI to the user, represented as a patron with a cursor for their head. They patron expresses they want a pink card, not a black one!" src="/images/docs/illustrations/i_rerender1.png" /> @@ -75,14 +75,14 @@ Once the component has been initially rendered, you can trigger further renders <Illustration caption="...render!" alt="The Card Chef gives React the pink Card." src="/images/docs/illustrations/i_rerender3.png" /> </IllustrationBlock> -## Step 2: React renders your components {/*step-2-react-renders-your-components*/} +## Step 2: React renders your Components {/*step-2-react-renders-your-components*/} -After you trigger a render, React calls your components to figure out what to display on screen. **"Rendering" is React calling your components.** +After you trigger a render, React calls your Components to figure out what to display on screen. **"Rendering" is React calling your components.** * **On initial render,** React will call the root component. -* **For subsequent renders,** React will call the function component whose state update triggered the render. +* **For subsequent renders,** React will call the function Component whose state update triggered the render. -This process is recursive: if the updated component returns some other component, React will render _that_ component next, and if that component also returns something, it will render _that_ component next, and so on. The process will continue until there are no more nested components and React knows exactly what should be displayed on screen. +This process is recursive: if the updated Component returns some other component, React will render _that_ Component next, and if that Component also returns something, it will render _that_ Component next, and so on. The process will continue until there are no more nested Components and React knows exactly what should be displayed on screen. In the following example, React will call `Gallery()` and `Image()` several times: @@ -131,7 +131,7 @@ img { margin: 0 10px 10px 0; } Rendering must always be a [pure calculation](/learn/keeping-components-pure): -* **Same inputs, same output.** Given the same inputs, a component should always return the same JSX. (When someone orders a salad with tomatoes, they should not receive a salad with onions!) +* **Same inputs, same output.** Given the same inputs, a Component should always return the same JSX. (When someone orders a salad with tomatoes, they should not receive a salad with onions!) * **It minds its own business.** It should not change any objects or variables that existed before rendering. (One order should not change anyone else's order.) Otherwise, you can encounter confusing bugs and unpredictable behavior as your codebase grows in complexity. When developing in "Strict Mode", React calls each component's function twice, which can help surface mistakes caused by impure functions. @@ -142,7 +142,7 @@ Otherwise, you can encounter confusing bugs and unpredictable behavior as your c #### Optimizing performance {/*optimizing-performance*/} -The default behavior of rendering all components nested within the updated component is not optimal for performance if the updated component is very high in the tree. If you run into a performance issue, there are several opt-in ways to solve it described in the [Performance](https://reactjs.org/docs/optimizing-performance.html) section. **Don't optimize prematurely!** +The default behavior of rendering all Components nested within the updated Component is not optimal for performance if the updated Component is very high in the tree. If you run into a performance issue, there are several opt-in ways to solve it described in the [Performance](https://reactjs.org/docs/optimizing-performance.html) section. **Don't optimize prematurely!** </DeepDive> @@ -153,7 +153,7 @@ After rendering (calling) your components, React will modify the DOM. * **For the initial render,** React will use the [`appendChild()`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) DOM API to put all the DOM nodes it has created on screen. * **For re-renders,** React will apply the minimal necessary operations (calculated while rendering!) to make the DOM match the latest rendering output. -**React only changes the DOM nodes if there's a difference between renders.** For example, here is a component that re-renders with different props passed from its parent every second. Notice how you can add some text into the `<input>`, updating its `value`, but the text doesn't disappear when the component re-renders: +**React only changes the DOM nodes if there's a difference between renders.** For example, here is a Component that re-renders with different props passed from its parent every second. Notice how you can add some text into the `<input>`, updating its `value`, but the text doesn't disappear when the Component re-renders: <Sandpack> diff --git a/src/content/learn/rendering-lists.md b/src/content/learn/rendering-lists.md index 32f81c44707..7f1889da542 100644 --- a/src/content/learn/rendering-lists.md +++ b/src/content/learn/rendering-lists.md @@ -4,14 +4,14 @@ title: Rendering Lists <Intro> -You will often want to display multiple similar components from a collection of data. You can use the [JavaScript array methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array#) to manipulate an array of data. On this page, you'll use [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) and [`map()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) with React to filter and transform your array of data into an array of components. +You will often want to display multiple similar Components from a collection of data. You can use the [JavaScript array methods](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array#) to manipulate an array of data. On this page, you'll use [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) and [`map()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map) with React to filter and transform your array of data into an array of components. </Intro> <YouWillLearn> -* How to render components from an array using JavaScript's `map()` -* How to render only specific components using JavaScript's `filter()` +* How to render Components from an array using JavaScript's `map()` +* How to render only specific Components using JavaScript's `filter()` * When and why to use React keys </YouWillLearn> @@ -30,7 +30,7 @@ Say that you have a list of content. </ul> ``` -The only difference among those list items is their contents, their data. You will often need to show several instances of the same component using different data when building interfaces: from lists of comments to galleries of profile images. In these situations, you can store that data in JavaScript objects and arrays and use methods like [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) and [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) to render lists of components from them. +The only difference among those list items is their contents, their data. You will often need to show several instances of the same Component using different data when building interfaces: from lists of comments to galleries of profile images. In these situations, you can store that data in JavaScript objects and arrays and use methods like [`map()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) and [`filter()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) to render lists of Components from them. Here’s a short example of how to generate a list of items from an array: @@ -52,7 +52,7 @@ const people = [ const listItems = people.map(person => <li>{person}</li>); ``` -3. **Return** `listItems` from your component wrapped in a `<ul>`: +3. **Return** `listItems` from your Component wrapped in a `<ul>`: ```js return <ul>{listItems}</ul>; @@ -288,7 +288,7 @@ JSX elements directly inside a `map()` call always need keys! </Note> -Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen `key` helps React infer what exactly has happened, and make the correct updates to the DOM tree. +Keys tell React which array item each Component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen `key` helps React infer what exactly has happened, and make the correct updates to the DOM tree. Rather than generating keys on the fly, you should include them in your data: @@ -421,9 +421,9 @@ File names in a folder and JSX keys in an array serve a similar purpose. They le You might be tempted to use an item's index in the array as its key. In fact, that's what React will use if you don't specify a `key` at all. But the order in which you render items will change over time if an item is inserted, deleted, or if the array gets reordered. Index as a key often leads to subtle and confusing bugs. -Similarly, do not generate keys on the fly, e.g. with `key={Math.random()}`. This will cause keys to never match up between renders, leading to all your components and DOM being recreated every time. Not only is this slow, but it will also lose any user input inside the list items. Instead, use a stable ID based on the data. +Similarly, do not generate keys on the fly, e.g. with `key={Math.random()}`. This will cause keys to never match up between renders, leading to all your Components and DOM being recreated every time. Not only is this slow, but it will also lose any user input inside the list items. Instead, use a stable ID based on the data. -Note that your components won't receive `key` as a prop. It's only used as a hint by React itself. If your component needs an ID, you have to pass it as a separate prop: `<Profile key={id} userId={id} />`. +Note that your Components won't receive `key` as a prop. It's only used as a hint by React itself. If your Component needs an ID, you have to pass it as a separate prop: `<Profile key={id} userId={id} />`. </Pitfall> @@ -431,10 +431,10 @@ Note that your components won't receive `key` as a prop. It's only used as a hin On this page you learned: -* How to move data out of components and into data structures like arrays and objects. -* How to generate sets of similar components with JavaScript's `map()`. +* How to move data out of Components and into data structures like arrays and objects. +* How to generate sets of similar Components with JavaScript's `map()`. * How to create arrays of filtered items with JavaScript's `filter()`. -* Why and how to set `key` on each component in a collection so React can keep track of each of them even if their position or data changes. +* Why and how to set `key` on each Component in a collection so React can keep track of each of them even if their position or data changes. </Recap> @@ -884,7 +884,7 @@ img { width: 100px; height: 100px; border-radius: 50%; } </Solution> -#### Nested lists in one component {/*nested-lists-in-one-component*/} +#### Nested lists in one Component {/*nested-lists-in-one-component*/} Make a list of recipes from this array! For each recipe in the array, display its name as an `<h2>` and list its ingredients in a `<ul>`. @@ -978,9 +978,9 @@ Each of the `recipes` already includes an `id` field, so that's what the outer l </Solution> -#### Extracting a list item component {/*extracting-a-list-item-component*/} +#### Extracting a list item Component {/*extracting-a-list-item-component*/} -This `RecipeList` component contains two nested `map` calls. To simplify it, extract a `Recipe` component from it which will accept `id`, `name`, and `ingredients` props. Where do you place the outer `key` and why? +This `RecipeList` Component contains two nested `map` calls. To simplify it, extract a `Recipe` Component from it which will accept `id`, `name`, and `ingredients` props. Where do you place the outer `key` and why? <Sandpack> @@ -1028,7 +1028,7 @@ export const recipes = [{ <Solution> -You can copy-paste the JSX from the outer `map` into a new `Recipe` component and return that JSX. Then you can change `recipe.name` to `name`, `recipe.id` to `id`, and so on, and pass them as props to the `Recipe`: +You can copy-paste the JSX from the outer `map` into a new `Recipe` Component and return that JSX. Then you can change `recipe.name` to `name`, `recipe.id` to `id`, and so on, and pass them as props to the `Recipe`: <Sandpack> diff --git a/src/content/learn/responding-to-events.md b/src/content/learn/responding-to-events.md index 17bd087ed25..d5b2132f295 100644 --- a/src/content/learn/responding-to-events.md +++ b/src/content/learn/responding-to-events.md @@ -106,10 +106,10 @@ When you write code inline, the same pitfall presents itself in a different way: | `<button onClick={() => alert('...')}>` | `<button onClick={alert('...')}>` | -Passing inline code like this won't fire on click—it fires every time the component renders: +Passing inline code like this won't fire on click—it fires every time the Component renders: ```jsx -// This alert fires when the component renders, not when clicked! +// This alert fires when the Component renders, not when clicked! <button onClick={alert('You clicked me!')}> ``` @@ -169,9 +169,9 @@ This lets these two buttons show different messages. Try changing the messages p ### Passing event handlers as props {/*passing-event-handlers-as-props*/} -Often you'll want the parent component to specify a child's event handler. Consider buttons: depending on where you're using a `Button` component, you might want to execute a different function—perhaps one plays a movie and another uploads an image. +Often you'll want the parent Component to specify a child's event handler. Consider buttons: depending on where you're using a `Button` component, you might want to execute a different function—perhaps one plays a movie and another uploads an image. -To do this, pass a prop the component receives from its parent as the event handler like so: +To do this, pass a prop the Component receives from its parent as the event handler like so: <Sandpack> @@ -220,18 +220,18 @@ button { margin-right: 10px; } </Sandpack> -Here, the `Toolbar` component renders a `PlayButton` and an `UploadButton`: +Here, the `Toolbar` Component renders a `PlayButton` and an `UploadButton`: - `PlayButton` passes `handlePlayClick` as the `onClick` prop to the `Button` inside. - `UploadButton` passes `() => alert('Uploading!')` as the `onClick` prop to the `Button` inside. -Finally, your `Button` component accepts a prop called `onClick`. It passes that prop directly to the built-in browser `<button>` with `onClick={onClick}`. This tells React to call the passed function on click. +Finally, your `Button` Component accepts a prop called `onClick`. It passes that prop directly to the built-in browser `<button>` with `onClick={onClick}`. This tells React to call the passed function on click. -If you use a [design system](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969), it's common for components like buttons to contain styling but not specify behavior. Instead, components like `PlayButton` and `UploadButton` will pass event handlers down. +If you use a [design system](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969), it's common for Components like buttons to contain styling but not specify behavior. Instead, Components like `PlayButton` and `UploadButton` will pass event handlers down. ### Naming event handler props {/*naming-event-handler-props*/} -Built-in components like `<button>` and `<div>` only support [browser event names](/reference/react-dom/components/common#common-props) like `onClick`. However, when you're building your own components, you can name their event handler props any way that you like. +Built-in Components like `<button>` and `<div>` only support [browser event names](/reference/react-dom/components/common#common-props) like `onClick`. However, when you're building your own components, you can name their event handler props any way that you like. By convention, event handler props should start with `on`, followed by a capital letter. @@ -268,9 +268,9 @@ button { margin-right: 10px; } </Sandpack> -In this example, `<button onClick={onSmash}>` shows that the browser `<button>` (lowercase) still needs a prop called `onClick`, but the prop name received by your custom `Button` component is up to you! +In this example, `<button onClick={onSmash}>` shows that the browser `<button>` (lowercase) still needs a prop called `onClick`, but the prop name received by your custom `Button` Component is up to you! -When your component supports multiple interactions, you might name event handler props for app-specific concepts. For example, this `Toolbar` component receives `onPlayMovie` and `onUploadImage` event handlers: +When your Component supports multiple interactions, you might name event handler props for app-specific concepts. For example, this `Toolbar` Component receives `onPlayMovie` and `onUploadImage` event handlers: <Sandpack> @@ -312,7 +312,7 @@ button { margin-right: 10px; } </Sandpack> -Notice how the `App` component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That's an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they're used later. +Notice how the `App` Component does not need to know *what* `Toolbar` will do with `onPlayMovie` or `onUploadImage`. That's an implementation detail of the `Toolbar`. Here, `Toolbar` passes them down as `onClick` handlers to its `Button`s, but it could later also trigger them on a keyboard shortcut. Naming props after app-specific interactions like `onPlayMovie` gives you the flexibility to change how they're used later. <Note> @@ -322,7 +322,7 @@ Make sure that you use the appropriate HTML tags for your event handlers. For ex ## Event propagation {/*event-propagation*/} -Event handlers will also catch events from any children your component might have. We say that an event "bubbles" or "propagates" up the tree: it starts with where the event happened, and then goes up the tree. +Event handlers will also catch events from any children your Component might have. We say that an event "bubbles" or "propagates" up the tree: it starts with where the event happened, and then goes up the tree. This `<div>` contains two buttons. Both the `<div>` *and* each button have their own `onClick` handlers. Which handlers do you think will fire when you click a button? @@ -367,7 +367,7 @@ All events propagate in React except `onScroll`, which only works on the JSX tag Event handlers receive an **event object** as their only argument. By convention, it's usually called `e`, which stands for "event". You can use this object to read information about the event. -That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` component does: +That event object also lets you stop the propagation. If you want to prevent an event from reaching parent components, you need to call `e.stopPropagation()` like this `Button` Component does: <Sandpack> @@ -460,7 +460,7 @@ function Button({ onClick, children }) { } ``` -You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child component handle the event, while also letting the parent component specify some additional behavior. Unlike propagation, it's not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event. +You could add more code to this handler before calling the parent `onClick` event handler, too. This pattern provides an *alternative* to propagation. It lets the child Component handle the event, while also letting the parent Component specify some additional behavior. Unlike propagation, it's not automatic. But the benefit of this pattern is that you can clearly follow the whole chain of code that executes as a result of some event. If you rely on propagation and it's difficult to trace which handlers execute and why, try this approach instead. @@ -623,9 +623,9 @@ export default function LightSwitch() { #### Wire up the events {/*wire-up-the-events*/} -This `ColorSwitch` component renders a button. It's supposed to change the page color. Wire it up to the `onChangeColor` event handler prop it receives from the parent so that clicking the button changes the color. +This `ColorSwitch` Component renders a button. It's supposed to change the page color. Wire it up to the `onChangeColor` event handler prop it receives from the parent so that clicking the button changes the color. -After you do this, notice that clicking the button also increments the page click counter. Your colleague who wrote the parent component insists that `onChangeColor` does not increment any counters. What else might be happening? Fix it so that clicking the button *only* changes the color, and does _not_ increment the counter. +After you do this, notice that clicking the button also increments the page click counter. Your colleague who wrote the parent Component insists that `onChangeColor` does not increment any counters. What else might be happening? Fix it so that clicking the button *only* changes the color, and does _not_ increment the counter. <Sandpack> diff --git a/src/content/learn/reusing-logic-with-custom-hooks.md b/src/content/learn/reusing-logic-with-custom-hooks.md index 13a556c7b15..a9451279356 100644 --- a/src/content/learn/reusing-logic-with-custom-hooks.md +++ b/src/content/learn/reusing-logic-with-custom-hooks.md @@ -17,14 +17,14 @@ React comes with several built-in Hooks like `useState`, `useContext`, and `useE </YouWillLearn> -## Custom Hooks: Sharing logic between components {/*custom-hooks-sharing-logic-between-components*/} +## Custom Hooks: Sharing logic between Components {/*custom-hooks-sharing-logic-between-components*/} Imagine you're developing an app that heavily relies on the network (as most apps do). You want to warn the user if their network connection has accidentally gone off while they were using your app. How would you go about it? It seems like you'll need two things in your component: 1. A piece of state that tracks whether the network is online. 2. An Effect that subscribes to the global [`online`](https://developer.mozilla.org/en-US/docs/Web/API/Window/online_event) and [`offline`](https://developer.mozilla.org/en-US/docs/Web/API/Window/offline_event) events, and updates that state. -This will keep your component [synchronized](/learn/synchronizing-with-effects) with the network status. You might start with something like this: +This will keep your Component [synchronized](/learn/synchronizing-with-effects) with the network status. You might start with something like this: <Sandpack> @@ -98,11 +98,11 @@ export default function SaveButton() { Verify that, if you turn off the network, the button will change its appearance. -These two components work fine, but the duplication in logic between them is unfortunate. It seems like even though they have different *visual appearance,* you want to reuse the logic between them. +These two Components work fine, but the duplication in logic between them is unfortunate. It seems like even though they have different *visual appearance,* you want to reuse the logic between them. -### Extracting your own custom Hook from a component {/*extracting-your-own-custom-hook-from-a-component*/} +### Extracting your own custom Hook from a Component {/*extracting-your-own-custom-hook-from-a-component*/} -Imagine for a moment that, similar to [`useState`](/reference/react/useState) and [`useEffect`](/reference/react/useEffect), there was a built-in `useOnlineStatus` Hook. Then both of these components could be simplified and you could remove the duplication between them: +Imagine for a moment that, similar to [`useState`](/reference/react/useState) and [`useEffect`](/reference/react/useEffect), there was a built-in `useOnlineStatus` Hook. Then both of these Components could be simplified and you could remove the duplication between them: ```js {2,7} function StatusBar() { @@ -125,7 +125,7 @@ function SaveButton() { } ``` -Although there is no such built-in Hook, you can write it yourself. Declare a function called `useOnlineStatus` and move all the duplicated code into it from the components you wrote earlier: +Although there is no such built-in Hook, you can write it yourself. Declare a function called `useOnlineStatus` and move all the duplicated code into it from the Components you wrote earlier: ```js {2-16} function useOnlineStatus() { @@ -148,7 +148,7 @@ function useOnlineStatus() { } ``` -At the end of the function, return `isOnline`. This lets your components read that value: +At the end of the function, return `isOnline`. This lets your Components read that value: <Sandpack> @@ -211,9 +211,9 @@ export function useOnlineStatus() { Verify that switching the network on and off updates both components. -Now your components don't have as much repetitive logic. **More importantly, the code inside them describes *what they want to do* (use the online status!) rather than *how to do it* (by subscribing to the browser events).** +Now your Components don't have as much repetitive logic. **More importantly, the code inside them describes *what they want to do* (use the online status!) rather than *how to do it* (by subscribing to the browser events).** -When you extract logic into custom Hooks, you can hide the gnarly details of how you deal with some external system or a browser API. The code of your components expresses your intent, not the implementation. +When you extract logic into custom Hooks, you can hide the gnarly details of how you deal with some external system or a browser API. The code of your Components expresses your intent, not the implementation. ### Hook names always start with `use` {/*hook-names-always-start-with-use*/} @@ -221,14 +221,14 @@ React applications are built from components. Components are built from Hooks, w You must follow these naming conventions: -1. **React component names must start with a capital letter,** like `StatusBar` and `SaveButton`. React components also need to return something that React knows how to display, like a piece of JSX. +1. **React Component names must start with a capital letter,** like `StatusBar` and `SaveButton`. React Components also need to return something that React knows how to display, like a piece of JSX. 2. **Hook names must start with `use` followed by a capital letter,** like [`useState`](/reference/react/useState) (built-in) or `useOnlineStatus` (custom, like earlier on the page). Hooks may return arbitrary values. -This convention guarantees that you can always look at a component and know where its state, Effects, and other React features might "hide". For example, if you see a `getColor()` function call inside your component, you can be sure that it can't possibly contain React state inside because its name doesn't start with `use`. However, a function call like `useOnlineStatus()` will most likely contain calls to other Hooks inside! +This convention guarantees that you can always look at a Component and know where its state, Effects, and other React features might "hide". For example, if you see a `getColor()` function call inside your component, you can be sure that it can't possibly contain React state inside because its name doesn't start with `use`. However, a function call like `useOnlineStatus()` will most likely contain calls to other Hooks inside! <Note> -If your linter is [configured for React,](/learn/editor-setup#linting) it will enforce this naming convention. Scroll up to the sandbox above and rename `useOnlineStatus` to `getOnlineStatus`. Notice that the linter won't allow you to call `useState` or `useEffect` inside of it anymore. Only Hooks and components can call other Hooks! +If your linter is [configured for React,](/learn/editor-setup#linting) it will enforce this naming convention. Scroll up to the sandbox above and rename `useOnlineStatus` to `getOnlineStatus`. Notice that the linter won't allow you to call `useState` or `useEffect` inside of it anymore. Only Hooks and Components can call other Hooks! </Note> @@ -285,13 +285,13 @@ function useAuth() { } ``` -Then components won't be able to call it conditionally. This will become important when you actually add Hook calls inside. If you don't plan to use Hooks inside it (now or later), don't make it a Hook. +Then Components won't be able to call it conditionally. This will become important when you actually add Hook calls inside. If you don't plan to use Hooks inside it (now or later), don't make it a Hook. </DeepDive> ### Custom Hooks let you share stateful logic, not state itself {/*custom-hooks-let-you-share-stateful-logic-not-state-itself*/} -In the earlier example, when you turned the network on and off, both components updated together. However, it's wrong to think that a single `isOnline` state variable is shared between them. Look at this code: +In the earlier example, when you turned the network on and off, both Components updated together. However, it's wrong to think that a single `isOnline` state variable is shared between them. Look at this code: ```js {2,7} function StatusBar() { @@ -430,7 +430,7 @@ input { margin-left: 10px; } Notice that it only declares *one* state variable called `value`. -However, the `Form` component calls `useFormInput` *two times:* +However, the `Form` Component calls `useFormInput` *two times:* ```js function Form() { @@ -620,7 +620,7 @@ export function useChatRoom({ serverUrl, roomId }) { } ``` -This lets your `ChatRoom` component call your custom Hook without worrying about how it works inside: +This lets your `ChatRoom` Component call your custom Hook without worrying about how it works inside: ```js {4-7} export default function ChatRoom({ roomId }) { @@ -833,7 +833,7 @@ export default function ChatRoom({ roomId }) { // ... ``` -Every time your `ChatRoom` component re-renders, it passes the latest `roomId` and `serverUrl` to your Hook. This is why your Effect re-connects to the chat whenever their values are different after a re-render. (If you ever worked with audio or video processing software, chaining Hooks like this might remind you of chaining visual or audio effects. It's as if the output of `useState` "feeds into" the input of the `useChatRoom`.) +Every time your `ChatRoom` Component re-renders, it passes the latest `roomId` and `serverUrl` to your Hook. This is why your Effect re-connects to the chat whenever their values are different after a re-render. (If you ever worked with audio or video processing software, chaining Hooks like this might remind you of chaining visual or audio effects. It's as if the output of `useState` "feeds into" the input of the `useChatRoom`.) ### Passing event handlers to custom Hooks {/*passing-event-handlers-to-custom-hooks*/} @@ -843,7 +843,7 @@ This section describes an **experimental API that has not yet been released** in </Wip> -As you start using `useChatRoom` in more components, you might want to let components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook: +As you start using `useChatRoom` in more components, you might want to let Components customize its behavior. For example, currently, the logic for what to do when a message arrives is hardcoded inside the Hook: ```js {9-11} export function useChatRoom({ serverUrl, roomId }) { @@ -899,7 +899,7 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { This will work, but there's one more improvement you can do when your custom Hook accepts event handlers. -Adding a dependency on `onReceiveMessage` is not ideal because it will cause the chat to re-connect every time the component re-renders. [Wrap this event handler into an Effect Event to remove it from the dependencies:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props) +Adding a dependency on `onReceiveMessage` is not ideal because it will cause the chat to re-connect every time the Component re-renders. [Wrap this event handler into an Effect Event to remove it from the dependencies:](/learn/removing-effect-dependencies#wrapping-an-event-handler-from-the-props) ```js {1,4,5,15,18} import { useEffect, useEffectEvent } from 'react'; @@ -923,7 +923,7 @@ export function useChatRoom({ serverUrl, roomId, onReceiveMessage }) { } ``` -Now the chat won't re-connect every time that the `ChatRoom` component re-renders. Here is a fully working demo of passing an event handler to a custom Hook that you can play with: +Now the chat won't re-connect every time that the `ChatRoom` Component re-renders. Here is a fully working demo of passing an event handler to a custom Hook that you can play with: <Sandpack> @@ -1099,7 +1099,7 @@ You don't need to extract a custom Hook for every little duplicated bit of code. However, whenever you write an Effect, consider whether it would be clearer to also wrap it in a custom Hook. [You shouldn't need Effects very often,](/learn/you-might-not-need-an-effect) so if you're writing one, it means that you need to "step outside React" to synchronize with some external system or to do something that React doesn't have a built-in API for. Wrapping it into a custom Hook lets you precisely communicate your intent and how the data flows through it. -For example, consider a `ShippingForm` component that displays two dropdowns: one shows the list of cities, and another shows the list of areas in the selected city. You might start with some code that looks like this: +For example, consider a `ShippingForm` Component that displays two dropdowns: one shows the list of cities, and another shows the list of areas in the selected city. You might start with some code that looks like this: ```js {3-16,20-35} function ShippingForm({ country }) { @@ -1141,7 +1141,7 @@ function ShippingForm({ country }) { // ... ``` -Although this code is quite repetitive, [it's correct to keep these Effects separate from each other.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) They synchronize two different things, so you shouldn't merge them into one Effect. Instead, you can simplify the `ShippingForm` component above by extracting the common logic between them into your own `useData` Hook: +Although this code is quite repetitive, [it's correct to keep these Effects separate from each other.](/learn/removing-effect-dependencies#is-your-effect-doing-several-unrelated-things) They synchronize two different things, so you shouldn't merge them into one Effect. Instead, you can simplify the `ShippingForm` Component above by extracting the common logic between them into your own `useData` Hook: ```js {2-18} function useData(url) { @@ -1165,7 +1165,7 @@ function useData(url) { } ``` -Now you can replace both Effects in the `ShippingForm` components with calls to `useData`: +Now you can replace both Effects in the `ShippingForm` Components with calls to `useData`: ```js {2,4} function ShippingForm({ country }) { @@ -1175,7 +1175,7 @@ function ShippingForm({ country }) { // ... ``` -Extracting a custom Hook makes the data flow explicit. You feed the `url` in and you get the `data` out. By "hiding" your Effect inside `useData`, you also prevent someone working on the `ShippingForm` component from adding [unnecessary dependencies](/learn/removing-effect-dependencies) to it. With time, most of your app's Effects will be in custom Hooks. +Extracting a custom Hook makes the data flow explicit. You feed the `url` in and you get the `data` out. By "hiding" your Effect inside `useData`, you also prevent someone working on the `ShippingForm` Component from adding [unnecessary dependencies](/learn/removing-effect-dependencies) to it. With time, most of your app's Effects will be in custom Hooks. <DeepDive> @@ -1331,7 +1331,7 @@ export function useOnlineStatus() { </Sandpack> -In the above example, `useOnlineStatus` is implemented with a pair of [`useState`](/reference/react/useState) and [`useEffect`.](/reference/react/useEffect) However, this isn't the best possible solution. There is a number of edge cases it doesn't consider. For example, it assumes that when the component mounts, `isOnline` is already `true`, but this may be wrong if the network already went offline. You can use the browser [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API to check for that, but using it directly would not work on the server for generating the initial HTML. In short, this code could be improved. +In the above example, `useOnlineStatus` is implemented with a pair of [`useState`](/reference/react/useState) and [`useEffect`.](/reference/react/useEffect) However, this isn't the best possible solution. There is a number of edge cases it doesn't consider. For example, it assumes that when the Component mounts, `isOnline` is already `true`, but this may be wrong if the network already went offline. You can use the browser [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/onLine) API to check for that, but using it directly would not work on the server for generating the initial HTML. In short, this code could be improved. Luckily, React 18 includes a dedicated API called [`useSyncExternalStore`](/reference/react/useSyncExternalStore) which takes care of all of these problems for you. Here is how your `useOnlineStatus` Hook, rewritten to take advantage of this new API: @@ -1410,10 +1410,10 @@ function SaveButton() { This is another reason for why wrapping Effects in custom Hooks is often beneficial: 1. You make the data flow to and from your Effects very explicit. -2. You let your components focus on the intent rather than on the exact implementation of your Effects. +2. You let your Components focus on the intent rather than on the exact implementation of your Effects. 3. When React adds new features, you can remove those Effects without changing any of your components. -Similar to a [design system,](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969) you might find it helpful to start extracting common idioms from your app's components into custom Hooks. This will keep your components' code focused on the intent, and let you avoid writing raw Effects very often. Many excellent custom Hooks are maintained by the React community. +Similar to a [design system,](https://uxdesign.cc/everything-you-need-to-know-about-design-systems-54b109851969) you might find it helpful to start extracting common idioms from your app's Components into custom Hooks. This will keep your components' code focused on the intent, and let you avoid writing raw Effects very often. Many excellent custom Hooks are maintained by the React community. <DeepDive> @@ -1431,7 +1431,7 @@ function ShippingForm({ country }) { // ... ``` -If you use custom Hooks like `useData` above in your app, it will require fewer changes to migrate to the eventually recommended approach than if you write raw Effects in every component manually. However, the old approach will still work fine, so if you feel happy writing raw Effects, you can continue to do that. +If you use custom Hooks like `useData` above in your app, it will require fewer changes to migrate to the eventually recommended approach than if you write raw Effects in every Component manually. However, the old approach will still work fine, so if you feel happy writing raw Effects, you can continue to do that. </DeepDive> @@ -1520,7 +1520,7 @@ html, body { min-height: 300px; } </Sandpack> -To make the component more readable, you might extract the logic into a `useFadeIn` custom Hook: +To make the Component more readable, you might extract the logic into a `useFadeIn` custom Hook: <Sandpack> @@ -1878,7 +1878,7 @@ Sometimes, you don't even need a Hook! - Custom Hooks must be named starting with `use` followed by a capital letter. - Custom Hooks only share stateful logic, not state itself. - You can pass reactive values from one Hook to another, and they stay up-to-date. -- All Hooks re-run every time your component re-renders. +- All Hooks re-run every time your Component re-renders. - The code of your custom Hooks should be pure, like your component's code. - Wrap event handlers received by custom Hooks into Effect Events. - Don't create custom Hooks like `useMount`. Keep their purpose specific. @@ -1890,7 +1890,7 @@ Sometimes, you don't even need a Hook! #### Extract a `useCounter` Hook {/*extract-a-usecounter-hook*/} -This component uses a state variable and an Effect to display a number that increments every second. Extract this logic into a custom Hook called `useCounter`. Your goal is to make the `Counter` component implementation look exactly like this: +This Component uses a state variable and an Effect to display a number that increments every second. Extract this logic into a custom Hook called `useCounter`. Your goal is to make the `Counter` Component implementation look exactly like this: ```js export default function Counter() { @@ -2160,7 +2160,7 @@ Note that there is a bit of a problem with this solution, which you'll solve in In this example, there are *two* separate intervals. -The `App` component calls `useCounter`, which calls `useInterval` to update the counter every second. But the `App` component *also* calls `useInterval` to randomly update the page background color every two seconds. +The `App` Component calls `useCounter`, which calls `useInterval` to update the counter every second. But the `App` Component *also* calls `useInterval` to randomly update the page background color every two seconds. For some reason, the callback that updates the page background never runs. Add some logs inside `useInterval`: diff --git a/src/content/learn/scaling-up-with-reducer-and-context.md b/src/content/learn/scaling-up-with-reducer-and-context.md index c3da0c6373d..942c22ab1d6 100644 --- a/src/content/learn/scaling-up-with-reducer-and-context.md +++ b/src/content/learn/scaling-up-with-reducer-and-context.md @@ -207,7 +207,7 @@ ul, li { margin: 0; padding: 0; } </Sandpack> -A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks` state and the `dispatch` function are only available in the top-level `TaskApp` component.** To let other components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component) the current state and the event handlers that change it as props. +A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks` state and the `dispatch` function are only available in the top-level `TaskApp` component.** To let other Components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component) the current state and the event handlers that change it as props. For example, `TaskApp` passes a list of tasks and the event handlers to `TaskList`: @@ -229,9 +229,9 @@ And `TaskList` passes the event handlers to `Task`: /> ``` -In a small example like this, this works well, but if you have tens or hundreds of components in the middle, passing down all state and functions can be quite frustrating! +In a small example like this, this works well, but if you have tens or hundreds of Components in the middle, passing down all state and functions can be quite frustrating! -This is why, as an alternative to passing them through props, you might want to put both the `tasks` state and the `dispatch` function [into context.](/learn/passing-data-deeply-with-context) **This way, any component below `TaskApp` in the tree can read the tasks and dispatch actions without the repetitive "prop drilling".** +This is why, as an alternative to passing them through props, you might want to put both the `tasks` state and the `dispatch` function [into context.](/learn/passing-data-deeply-with-context) **This way, any Component below `TaskApp` in the tree can read the tasks and dispatch actions without the repetitive "prop drilling".** Here is how you can combine a reducer with context: @@ -250,7 +250,7 @@ const [tasks, dispatch] = useReducer(tasksReducer, initialTasks); To pass them down the tree, you will [create](/learn/passing-data-deeply-with-context#step-2-use-the-context) two separate contexts: - `TasksContext` provides the current list of tasks. -- `TasksDispatchContext` provides the function that lets components dispatch actions. +- `TasksDispatchContext` provides the function that lets Components dispatch actions. Export them from a separate file so that you can later import them from other files: @@ -685,7 +685,7 @@ Now you don't need to pass the list of tasks or the event handlers down the tree </TasksContext.Provider> ``` -Instead, any component that needs the task list can read it from the `TaskContext`: +Instead, any Component that needs the task list can read it from the `TaskContext`: ```js {2} export default function TaskList() { @@ -693,7 +693,7 @@ export default function TaskList() { // ... ``` -To update the task list, any component can read the `dispatch` function from context and call it: +To update the task list, any Component can read the `dispatch` function from context and call it: ```js {3,9-13} export default function AddTask() { @@ -713,7 +713,7 @@ export default function AddTask() { // ... ``` -**The `TaskApp` component does not pass any event handlers down, and the `TaskList` does not pass any event handlers to the `Task` component either.** Each component reads the context that it needs: +**The `TaskApp` Component does not pass any event handlers down, and the `TaskList` does not pass any event handlers to the `Task` Component either.** Each Component reads the context that it needs: <Sandpack> @@ -897,11 +897,11 @@ ul, li { margin: 0; padding: 0; } </Sandpack> -**The state still "lives" in the top-level `TaskApp` component, managed with `useReducer`.** But its `tasks` and `dispatch` are now available to every component below in the tree by importing and using these contexts. +**The state still "lives" in the top-level `TaskApp` component, managed with `useReducer`.** But its `tasks` and `dispatch` are now available to every Component below in the tree by importing and using these contexts. ## Moving all wiring into a single file {/*moving-all-wiring-into-a-single-file*/} -You don't have to do this, but you could further declutter the components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations: +You don't have to do this, but you could further declutter the Components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations: ```js import { createContext } from 'react'; @@ -910,10 +910,10 @@ export const TasksContext = createContext(null); export const TasksDispatchContext = createContext(null); ``` -This file is about to get crowded! You'll move the reducer into that same file. Then you'll declare a new `TasksProvider` component in the same file. This component will tie all the pieces together: +This file is about to get crowded! You'll move the reducer into that same file. Then you'll declare a new `TasksProvider` Component in the same file. This Component will tie all the pieces together: 1. It will manage the state with a reducer. -2. It will provide both contexts to components below. +2. It will provide both contexts to Components below. 3. It will [take `children` as a prop](/learn/passing-props-to-a-component#passing-jsx-as-children) so you can pass JSX to it. ```js @@ -1133,14 +1133,14 @@ export function useTasksDispatch() { } ``` -When a component needs to read context, it can do it through these functions: +When a Component needs to read context, it can do it through these functions: ```js const tasks = useTasks(); const dispatch = useTasksDispatch(); ``` -This doesn't change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the components clean and uncluttered, focused on what they display rather than where they get the data:** +This doesn't change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the Components clean and uncluttered, focused on what they display rather than where they get the data:** <Sandpack> @@ -1340,7 +1340,7 @@ ul, li { margin: 0; padding: 0; } </Sandpack> -You can think of `TasksProvider` as a part of the screen that knows how to deal with tasks, `useTasks` as a way to read them, and `useTasksDispatch` as a way to update them from any component below in the tree. +You can think of `TasksProvider` as a part of the screen that knows how to deal with tasks, `useTasks` as a way to read them, and `useTasksDispatch` as a way to update them from any Component below in the tree. <Note> @@ -1352,13 +1352,13 @@ As your app grows, you may have many context-reducer pairs like this. This is a <Recap> -- You can combine reducer with context to let any component read and update state above it. -- To provide state and the dispatch function to components below: +- You can combine reducer with context to let any Component read and update state above it. +- To provide state and the dispatch function to Components below: 1. Create two contexts (for state and for dispatch functions). - 2. Provide both contexts from the component that uses the reducer. - 3. Use either context from components that need to read them. -- You can further declutter the components by moving all wiring into one file. - - You can export a component like `TasksProvider` that provides context. + 2. Provide both contexts from the Component that uses the reducer. + 3. Use either context from Components that need to read them. +- You can further declutter the Components by moving all wiring into one file. + - You can export a Component like `TasksProvider` that provides context. - You can also export custom Hooks like `useTasks` and `useTasksDispatch` to read it. - You can have many context-reducer pairs like this in your app. diff --git a/src/content/learn/separating-events-from-effects.md b/src/content/learn/separating-events-from-effects.md index ac65d2b6071..29e6e2c4b26 100644 --- a/src/content/learn/separating-events-from-effects.md +++ b/src/content/learn/separating-events-from-effects.md @@ -24,7 +24,7 @@ First, let's recap the difference between event handlers and Effects. Imagine you're implementing a chat room component. Your requirements look like this: -1. Your component should automatically connect to the selected chat room. +1. Your Component should automatically connect to the selected chat room. 1. When you click the "Send" button, it should send a message to the chat. Let's say you've already implemented the code for them, but you're not sure where to put it. Should you use event handlers or Effects? Every time you need to answer this question, consider [*why* the code needs to run.](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) @@ -54,9 +54,9 @@ With an event handler, you can be sure that `sendMessage(message)` will *only* r ### Effects run whenever synchronization is needed {/*effects-run-whenever-synchronization-is-needed*/} -Recall that you also need to keep the component connected to the chat room. Where does that code go? +Recall that you also need to keep the Component connected to the chat room. Where does that code go? -The *reason* to run this code is not some particular interaction. It doesn't matter why or how the user navigated to the chat room screen. Now that they're looking at it and could interact with it, the component needs to stay connected to the selected chat server. Even if the chat room component was the initial screen of your app, and the user has not performed any interactions at all, you would *still* need to connect. This is why it's an Effect: +The *reason* to run this code is not some particular interaction. It doesn't matter why or how the user navigated to the chat room screen. Now that they're looking at it and could interact with it, the Component needs to stay connected to the selected chat server. Even if the chat room Component was the initial screen of your app, and the user has not performed any interactions at all, you would *still* need to connect. This is why it's an Effect: ```js {3-9} function ChatRoom({ roomId }) { @@ -72,7 +72,7 @@ function ChatRoom({ roomId }) { } ``` -With this code, you can be sure that there is always an active connection to the currently selected chat server, *regardless* of the specific interactions performed by the user. Whether the user has only opened your app, selected a different room, or navigated to another screen and back, your Effect ensures that the component will *remain synchronized* with the currently selected room, and will [re-connect whenever it's necessary.](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once) +With this code, you can be sure that there is always an active connection to the currently selected chat server, *regardless* of the specific interactions performed by the user. Whether the user has only opened your app, selected a different room, or navigated to another screen and back, your Effect ensures that the Component will *remain synchronized* with the currently selected room, and will [re-connect whenever it's necessary.](/learn/lifecycle-of-reactive-effects#why-synchronization-may-need-to-happen-more-than-once) <Sandpack> @@ -597,7 +597,7 @@ function Page() { } ``` -Later, you add multiple routes to your site. Now your `Page` component receives a `url` prop with the current path. You want to pass the `url` as a part of your `logVisit` call, but the dependency linter complains: +Later, you add multiple routes to your site. Now your `Page` Component receives a `url` prop with the current path. You want to pass the `url` as a part of your `logVisit` call, but the dependency linter complains: ```js {1,3} function Page({ url }) { @@ -790,7 +790,7 @@ body { </Sandpack> -The problem with this code is in suppressing the dependency linter. If you remove the suppression, you'll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time! +The problem with this code is in suppressing the dependency linter. If you remove the suppression, you'll see that this Effect should depend on the `handleMove` function. This makes sense: `handleMove` is declared inside the Component body, which makes it a reactive value. Every reactive value must be specified as a dependency, or it can potentially get stale over time! The author of the original code has "lied" to React by saying that the Effect does not depend (`[]`) on any reactive values. This is why React did not re-synchronize the Effect after `canMove` has changed (and `handleMove` with it). Because React did not re-synchronize the Effect, the `handleMove` attached as a listener is the `handleMove` function created during the initial render. During the initial render, `canMove` was `true`, which is why `handleMove` from the initial render will forever see that value. @@ -887,7 +887,7 @@ This section describes an **experimental API that has not yet been released** in Effect Events are very limited in how you can use them: * **Only call them from inside Effects.** -* **Never pass them to other components or Hooks.** +* **Never pass them to other Components or Hooks.** For example, don't declare and pass an Effect Event like this: @@ -953,7 +953,7 @@ Effect Events are non-reactive "pieces" of your Effect code. They should be next - Logic inside Effects is reactive. - You can move non-reactive logic from Effects into Effect Events. - Only call Effect Events from inside Effects. -- Don't pass Effect Events to other components or Hooks. +- Don't pass Effect Events to other Components or Hooks. </Recap> @@ -961,7 +961,7 @@ Effect Events are non-reactive "pieces" of your Effect code. They should be next #### Fix a variable that doesn't update {/*fix-a-variable-that-doesnt-update*/} -This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable. You can control the `increment` variable with the plus and minus buttons. +This `Timer` Component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable. You can control the `increment` variable with the plus and minus buttons. However, no matter how many times you click the plus button, the counter is still incremented by one every second. What's wrong with this code? Why is `increment` always equal to `1` inside the Effect's code? Find the mistake and fix it. @@ -1076,7 +1076,7 @@ Now, when `increment` changes, React will re-synchronize your Effect, which will #### Fix a freezing counter {/*fix-a-freezing-counter*/} -This `Timer` component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable, which you can control it with the plus and minus buttons. For example, try pressing the plus button nine times, and notice that the `count` now increases each second by ten rather than by one. +This `Timer` Component keeps a `count` state variable which increases every second. The value by which it's increasing is stored in the `increment` state variable, which you can control it with the plus and minus buttons. For example, try pressing the plus button nine times, and notice that the `count` now increases each second by ten rather than by one. There is a small issue with this user interface. You might notice that if you keep pressing the plus or minus buttons faster than once per second, the timer itself seems to pause. It only resumes after a second passes since the last time you've pressed either button. Find why this is happening, and fix the issue so that the timer ticks on *every* second without interruptions. @@ -1408,7 +1408,7 @@ In general, you should be suspicious of functions like `onMount` that focus on t #### Fix a delayed notification {/*fix-a-delayed-notification*/} -When you join a chat room, this component shows a notification. However, it doesn't show the notification immediately. Instead, the notification is artificially delayed by two seconds so that the user has a chance to look around the UI. +When you join a chat room, this Component shows a notification. However, it doesn't show the notification immediately. Instead, the notification is artificially delayed by two seconds so that the user has a chance to look around the UI. This almost works, but there is a bug. Try changing the dropdown from "general" to "travel" and then to "music" very quickly. If you do it fast enough, you will see two notifications (as expected!) but they will *both* say "Welcome to music". diff --git a/src/content/learn/sharing-state-between-components.md b/src/content/learn/sharing-state-between-components.md index 52eaf28f85d..c4ec58f9ce2 100644 --- a/src/content/learn/sharing-state-between-components.md +++ b/src/content/learn/sharing-state-between-components.md @@ -4,26 +4,26 @@ title: Sharing State Between Components <Intro> -Sometimes, you want the state of two components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as *lifting state up,* and it's one of the most common things you will do writing React code. +Sometimes, you want the state of two Components to always change together. To do it, remove state from both of them, move it to their closest common parent, and then pass it down to them via props. This is known as *lifting state up,* and it's one of the most common things you will do writing React code. </Intro> <YouWillLearn> -- How to share state between components by lifting it up +- How to share state between Components by lifting it up - What are controlled and uncontrolled components </YouWillLearn> ## Lifting state up by example {/*lifting-state-up-by-example*/} -In this example, a parent `Accordion` component renders two separate `Panel`s: +In this example, a parent `Accordion` Component renders two separate `Panel`s: * `Accordion` - `Panel` - `Panel` -Each `Panel` component has a boolean `isActive` state that determines whether its content is visible. +Each `Panel` Component has a boolean `isActive` state that determines whether its content is visible. Press the Show button for both panels: @@ -77,13 +77,13 @@ Notice how pressing one panel's button does not affect the other panel--they are <DiagramGroup> -<Diagram name="sharing_state_child" height={367} width={477} alt="Diagram showing a tree of three components, one parent labeled Accordion and two children labeled Panel. Both Panel components contain isActive with value false."> +<Diagram name="sharing_state_child" height={367} width={477} alt="Diagram showing a tree of three components, one parent labeled Accordion and two children labeled Panel. Both Panel Components contain isActive with value false."> Initially, each `Panel`'s `isActive` state is `false`, so they both appear collapsed </Diagram> -<Diagram name="sharing_state_child_clicked" height={367} width={480} alt="The same diagram as the previous, with the isActive of the first child Panel component highlighted indicating a click with the isActive value set to true. The second Panel component still contains value false." > +<Diagram name="sharing_state_child_clicked" height={367} width={480} alt="The same diagram as the previous, with the isActive of the first child Panel Component highlighted indicating a click with the isActive value set to true. The second Panel Component still contains value false." > Clicking either `Panel`'s button will only update that `Panel`'s `isActive` state alone @@ -93,17 +93,17 @@ Clicking either `Panel`'s button will only update that `Panel`'s `isActive` stat **But now let's say you want to change it so that only one panel is expanded at any given time.** With that design, expanding the second panel should collapse the first one. How would you do that? -To coordinate these two panels, you need to "lift their state up" to a parent component in three steps: +To coordinate these two panels, you need to "lift their state up" to a parent Component in three steps: 1. **Remove** state from the child components. 2. **Pass** hardcoded data from the common parent. 3. **Add** state to the common parent and pass it down together with the event handlers. -This will allow the `Accordion` component to coordinate both `Panel`s and only expand one at a time. +This will allow the `Accordion` Component to coordinate both `Panel`s and only expand one at a time. -### Step 1: Remove state from the child components {/*step-1-remove-state-from-the-child-components*/} +### Step 1: Remove state from the child Components {/*step-1-remove-state-from-the-child-components*/} -You will give control of the `Panel`'s `isActive` to its parent component. This means that the parent component will pass `isActive` to `Panel` as a prop instead. Start by **removing this line** from the `Panel` component: +You will give control of the `Panel`'s `isActive` to its parent component. This means that the parent Component will pass `isActive` to `Panel` as a prop instead. Start by **removing this line** from the `Panel` component: ```js const [isActive, setIsActive] = useState(false); @@ -115,17 +115,17 @@ And instead, add `isActive` to the `Panel`'s list of props: function Panel({ title, children, isActive }) { ``` -Now the `Panel`'s parent component can *control* `isActive` by [passing it down as a prop.](/learn/passing-props-to-a-component) Conversely, the `Panel` component now has *no control* over the value of `isActive`--it's now up to the parent component! +Now the `Panel`'s parent Component can *control* `isActive` by [passing it down as a prop.](/learn/passing-props-to-a-component) Conversely, the `Panel` Component now has *no control* over the value of `isActive`--it's now up to the parent component! ### Step 2: Pass hardcoded data from the common parent {/*step-2-pass-hardcoded-data-from-the-common-parent*/} -To lift state up, you must locate the closest common parent component of *both* of the child components that you want to coordinate: +To lift state up, you must locate the closest common parent Component of *both* of the child Components that you want to coordinate: * `Accordion` *(closest common parent)* - `Panel` - `Panel` -In this example, it's the `Accordion` component. Since it's above both panels and can control their props, it will become the "source of truth" for which panel is currently active. Make the `Accordion` component pass a hardcoded value of `isActive` (for example, `true`) to both panels: +In this example, it's the `Accordion` component. Since it's above both panels and can control their props, it will become the "source of truth" for which panel is currently active. Make the `Accordion` Component pass a hardcoded value of `isActive` (for example, `true`) to both panels: <Sandpack> @@ -172,13 +172,13 @@ h3, p { margin: 5px 0px; } </Sandpack> -Try editing the hardcoded `isActive` values in the `Accordion` component and see the result on the screen. +Try editing the hardcoded `isActive` values in the `Accordion` Component and see the result on the screen. ### Step 3: Add state to the common parent {/*step-3-add-state-to-the-common-parent*/} Lifting state up often changes the nature of what you're storing as state. -In this case, only one panel should be active at a time. This means that the `Accordion` common parent component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable: +In this case, only one panel should be active at a time. This means that the `Accordion` common parent Component needs to keep track of *which* panel is the active one. Instead of a `boolean` value, it could use a number as the index of the active `Panel` for the state variable: ```js const [activeIndex, setActiveIndex] = useState(0); @@ -186,7 +186,7 @@ const [activeIndex, setActiveIndex] = useState(0); When the `activeIndex` is `0`, the first panel is active, and when it's `1`, it's the second one. -Clicking the "Show" button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can't set the `activeIndex` state directly because it's defined inside the `Accordion`. The `Accordion` component needs to *explicitly allow* the `Panel` component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props): +Clicking the "Show" button in either `Panel` needs to change the active index in `Accordion`. A `Panel` can't set the `activeIndex` state directly because it's defined inside the `Accordion`. The `Accordion` Component needs to *explicitly allow* the `Panel` Component to change its state by [passing an event handler down as a prop](/learn/responding-to-events#passing-event-handlers-as-props): ```js <> @@ -266,7 +266,7 @@ h3, p { margin: 5px 0px; } </Sandpack> -This completes lifting state up! Moving state into the common parent component allowed you to coordinate the two panels. Using the active index instead of two "is shown" flags ensured that only one panel is active at a given time. And passing down the event handler to the child allowed the child to change the parent's state. +This completes lifting state up! Moving state into the common parent Component allowed you to coordinate the two panels. Using the active index instead of two "is shown" flags ensured that only one panel is active at a given time. And passing down the event handler to the child allowed the child to change the parent's state. <DiagramGroup> @@ -276,7 +276,7 @@ Initially, `Accordion`'s `activeIndex` is `0`, so the first `Panel` receives `is </Diagram> -<Diagram name="sharing_state_parent_clicked" height={385} width={521} alt="The same diagram as the previous, with the activeIndex value of the parent Accordion component highlighted indicating a click with the value changed to one. The flow to both of the children Panel components is also highlighted, and the isActive value passed to each child is set to the opposite: false for the first Panel and true for the second one." > +<Diagram name="sharing_state_parent_clicked" height={385} width={521} alt="The same diagram as the previous, with the activeIndex value of the parent Accordion Component highlighted indicating a click with the value changed to one. The flow to both of the children Panel Components is also highlighted, and the isActive value passed to each child is set to the opposite: false for the first Panel and true for the second one." > When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receives `isActive = true` instead @@ -286,15 +286,15 @@ When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receiv <DeepDive> -#### Controlled and uncontrolled components {/*controlled-and-uncontrolled-components*/} +#### Controlled and uncontrolled Components {/*controlled-and-uncontrolled-components*/} -It is common to call a component with some local state "uncontrolled". For example, the original `Panel` component with an `isActive` state variable is uncontrolled because its parent cannot influence whether the panel is active or not. +It is common to call a Component with some local state "uncontrolled". For example, the original `Panel` Component with an `isActive` state variable is uncontrolled because its parent cannot influence whether the panel is active or not. -In contrast, you might say a component is "controlled" when the important information in it is driven by props rather than its own local state. This lets the parent component fully specify its behavior. The final `Panel` component with the `isActive` prop is controlled by the `Accordion` component. +In contrast, you might say a Component is "controlled" when the important information in it is driven by props rather than its own local state. This lets the parent Component fully specify its behavior. The final `Panel` Component with the `isActive` prop is controlled by the `Accordion` component. -Uncontrolled components are easier to use within their parents because they require less configuration. But they're less flexible when you want to coordinate them together. Controlled components are maximally flexible, but they require the parent components to fully configure them with props. +Uncontrolled Components are easier to use within their parents because they require less configuration. But they're less flexible when you want to coordinate them together. Controlled Components are maximally flexible, but they require the parent Components to fully configure them with props. -In practice, "controlled" and "uncontrolled" aren't strict technical terms--each component usually has some mix of both local state and props. However, this is a useful way to talk about how components are designed and what capabilities they offer. +In practice, "controlled" and "uncontrolled" aren't strict technical terms--each Component usually has some mix of both local state and props. However, this is a useful way to talk about how Components are designed and what capabilities they offer. When writing a component, consider which information in it should be controlled (via props), and which information should be uncontrolled (via state). But you can always change your mind and refactor later. @@ -302,9 +302,9 @@ When writing a component, consider which information in it should be controlled ## A single source of truth for each state {/*a-single-source-of-truth-for-each-state*/} -In a React application, many components will have their own state. Some state may "live" close to the leaf components (components at the bottom of the tree) like inputs. Other state may "live" closer to the top of the app. For example, even client-side routing libraries are usually implemented by storing the current route in the React state, and passing it down by props! +In a React application, many Components will have their own state. Some state may "live" close to the leaf Components (components at the bottom of the tree) like inputs. Other state may "live" closer to the top of the app. For example, even client-side routing libraries are usually implemented by storing the current route in the React state, and passing it down by props! -**For each unique piece of state, you will choose the component that "owns" it.** This principle is also known as having a ["single source of truth".](https://en.wikipedia.org/wiki/Single_source_of_truth) It doesn't mean that all state lives in one place--but that for _each_ piece of state, there is a _specific_ component that holds that piece of information. Instead of duplicating shared state between components, *lift it up* to their common shared parent, and *pass it down* to the children that need it. +**For each unique piece of state, you will choose the Component that "owns" it.** This principle is also known as having a ["single source of truth".](https://en.wikipedia.org/wiki/Single_source_of_truth) It doesn't mean that all state lives in one place--but that for _each_ piece of state, there is a _specific_ Component that holds that piece of information. Instead of duplicating shared state between components, *lift it up* to their common shared parent, and *pass it down* to the children that need it. Your app will change as you work on it. It is common that you will move state down or back up while you're still figuring out where each piece of the state "lives". This is all part of the process! @@ -315,7 +315,7 @@ To see what this feels like in practice with a few more components, read [Thinki * When you want to coordinate two components, move their state to their common parent. * Then pass the information down through props from their common parent. * Finally, pass the event handlers down so that the children can change the parent's state. -* It's useful to consider components as "controlled" (driven by props) or "uncontrolled" (driven by state). +* It's useful to consider Components as "controlled" (driven by props) or "uncontrolled" (driven by state). </Recap> @@ -374,7 +374,7 @@ label { display: block; } <Solution> -Move the `text` state variable into the parent component along with the `handleChange` handler. Then pass them down as props to both of the `Input` components. This will keep them in sync. +Move the `text` state variable into the parent Component along with the `handleChange` handler. Then pass them down as props to both of the `Input` components. This will keep them in sync. <Sandpack> @@ -429,7 +429,7 @@ label { display: block; } #### Filtering a list {/*filtering-a-list*/} -In this example, the `SearchBar` has its own `query` state that controls the text input. Its parent `FilterableList` component displays a `List` of items, but it doesn't take the search query into account. +In this example, the `SearchBar` has its own `query` state that controls the text input. Its parent `FilterableList` Component displays a `List` of items, but it doesn't take the search query into account. Use the `filterItems(foods, query)` function to filter the list according to the search query. To test your changes, verify that typing "s" into the input filters down the list to "Sushi", "Shish kebab", and "Dim sum". diff --git a/src/content/learn/start-a-new-react-project.md b/src/content/learn/start-a-new-react-project.md index bd5ba6c50e5..5cfe5544bc4 100644 --- a/src/content/learn/start-a-new-react-project.md +++ b/src/content/learn/start-a-new-react-project.md @@ -21,7 +21,7 @@ You can definitely use React without a framework--that's how you'd [use React fo Here's why. -Even if you don't need routing or data fetching at first, you'll likely want to add some libraries for them. As your JavaScript bundle grows with every new feature, you might have to figure out how to split code for every route individually. As your data fetching needs get more complex, you are likely to encounter server-client network waterfalls that make your app feel very slow. As your audience includes more users with poor network conditions and low-end devices, you might need to generate HTML from your components to display content early--either on the server, or during the build time. Changing your setup to run some of your code on the server or during the build can be very tricky. +Even if you don't need routing or data fetching at first, you'll likely want to add some libraries for them. As your JavaScript bundle grows with every new feature, you might have to figure out how to split code for every route individually. As your data fetching needs get more complex, you are likely to encounter server-client network waterfalls that make your app feel very slow. As your audience includes more users with poor network conditions and low-end devices, you might need to generate HTML from your Components to display content early--either on the server, or during the build time. Changing your setup to run some of your code on the server or during the build can be very tricky. **These problems are not React-specific. This is why Svelte has SvelteKit, Vue has Nuxt, and so on.** To solve these problems on your own, you'll need to integrate your bundler with your router and with your data fetching library. It's not hard to get an initial setup working, but there are a lot of subtleties involved in making an app that loads quickly even as it grows over time. You'll want to send down the minimal amount of app code but do so in a single client–server roundtrip, in parallel with any data required for the page. You'll likely want the page to be interactive before your JavaScript code even runs, to support progressive enhancement. You may want to generate a folder of fully static HTML files for your marketing pages that can be hosted anywhere and still work with JavaScript disabled. Building these capabilities yourself takes real work. @@ -91,7 +91,7 @@ These features are getting closer to being production-ready every day, and we've ### Next.js (App Router) {/*nextjs-app-router*/} -**[Next.js's App Router](https://nextjs.org/docs) is a redesign of the Next.js APIs aiming to fulfill the React team’s full-stack architecture vision.** It lets you fetch data in asynchronous components that run on the server or even during the build. +**[Next.js's App Router](https://nextjs.org/docs) is a redesign of the Next.js APIs aiming to fulfill the React team’s full-stack architecture vision.** It lets you fetch data in asynchronous Components that run on the server or even during the build. Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports [static export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) which doesn't require a server. @@ -99,12 +99,12 @@ Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.j #### Which features make up the React team’s full-stack architecture vision? {/*which-features-make-up-the-react-teams-full-stack-architecture-vision*/} -Next.js's App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive components in a single React tree. +Next.js's App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive Components in a single React tree. -For example, you can write a server-only React component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components: +For example, you can write a server-only React Component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components: ```js -// This component runs *only* on the server (or during the build). +// This Component runs *only* on the server (or during the build). async function Talks({ confId }) { // 1. You're on the server, so you can talk to your data layer. API endpoint not required. const talks = await db.Talks.findAll({ confId }); @@ -112,7 +112,7 @@ async function Talks({ confId }) { // 2. Add any amount of rendering logic. It won't make your JavaScript bundle larger. const videos = talks.map(talk => talk.video); - // 3. Pass the data down to the components that will run in the browser. + // 3. Pass the data down to the Components that will run in the browser. return <SearchableVideoList videos={videos} />; } ``` diff --git a/src/content/learn/state-a-components-memory.md b/src/content/learn/state-a-components-memory.md index 75a1fd0b91e..18d9aa6f710 100644 --- a/src/content/learn/state-a-components-memory.md +++ b/src/content/learn/state-a-components-memory.md @@ -19,7 +19,7 @@ Components often need to change what's on the screen as a result of an interacti ## When a regular variable isn’t enough {/*when-a-regular-variable-isnt-enough*/} -Here's a component that renders a sculpture image. Clicking the "Next" button should show the next sculpture by changing the `index` to `1`, then `2`, and so on. However, this **won't work** (you can try it!): +Here's a Component that renders a sculpture image. Clicking the "Next" button should show the next sculpture by changing the `index` to `1`, then `2`, and so on. However, this **won't work** (you can try it!): <Sandpack> @@ -153,18 +153,18 @@ button { The `handleClick` event handler is updating a local variable, `index`. But two things prevent that change from being visible: -1. **Local variables don't persist between renders.** When React renders this component a second time, it renders it from scratch—it doesn't consider any changes to the local variables. -2. **Changes to local variables won't trigger renders.** React doesn't realize it needs to render the component again with the new data. +1. **Local variables don't persist between renders.** When React renders this Component a second time, it renders it from scratch—it doesn't consider any changes to the local variables. +2. **Changes to local variables won't trigger renders.** React doesn't realize it needs to render the Component again with the new data. -To update a component with new data, two things need to happen: +To update a Component with new data, two things need to happen: 1. **Retain** the data between renders. -2. **Trigger** React to render the component with new data (re-rendering). +2. **Trigger** React to render the Component with new data (re-rendering). The [`useState`](/reference/react/useState) Hook provides those two things: 1. A **state variable** to retain the data between renders. -2. A **state setter function** to update the variable and trigger React to render the component again. +2. A **state setter function** to update the variable and trigger React to render the Component again. ## Adding a state variable {/*adding-a-state-variable*/} @@ -341,13 +341,13 @@ State is just one of those features, but you will meet the other Hooks later. <Pitfall> -**Hooks—functions starting with `use`—can only be called at the top level of your components or [your own Hooks.](/learn/reusing-logic-with-custom-hooks)** You can't call Hooks inside conditions, loops, or other nested functions. Hooks are functions, but it's helpful to think of them as unconditional declarations about your component's needs. You "use" React features at the top of your component similar to how you "import" modules at the top of your file. +**Hooks—functions starting with `use`—can only be called at the top level of your Components or [your own Hooks.](/learn/reusing-logic-with-custom-hooks)** You can't call Hooks inside conditions, loops, or other nested functions. Hooks are functions, but it's helpful to think of them as unconditional declarations about your component's needs. You "use" React features at the top of your Component similar to how you "import" modules at the top of your file. </Pitfall> ### Anatomy of `useState` {/*anatomy-of-usestate*/} -When you call [`useState`](/reference/react/useState), you are telling React that you want this component to remember something: +When you call [`useState`](/reference/react/useState), you are telling React that you want this Component to remember something: ```js const [index, setIndex] = useState(0); @@ -363,10 +363,10 @@ The convention is to name this pair like `const [something, setSomething]`. You The only argument to `useState` is the **initial value** of your state variable. In this example, the `index`'s initial value is set to `0` with `useState(0)`. -Every time your component renders, `useState` gives you an array containing two values: +Every time your Component renders, `useState` gives you an array containing two values: 1. The **state variable** (`index`) with the value you stored. -2. The **state setter function** (`setIndex`) which can update the state variable and trigger React to render the component again. +2. The **state setter function** (`setIndex`) which can update the state variable and trigger React to render the Component again. Here's how that happens in action: @@ -374,14 +374,14 @@ Here's how that happens in action: const [index, setIndex] = useState(0); ``` -1. **Your component renders the first time.** Because you passed `0` to `useState` as the initial value for `index`, it will return `[0, setIndex]`. React remembers `0` is the latest state value. +1. **Your Component renders the first time.** Because you passed `0` to `useState` as the initial value for `index`, it will return `[0, setIndex]`. React remembers `0` is the latest state value. 2. **You update the state.** When a user clicks the button, it calls `setIndex(index + 1)`. `index` is `0`, so it's `setIndex(1)`. This tells React to remember `index` is `1` now and triggers another render. 3. **Your component's second render.** React still sees `useState(0)`, but because React *remembers* that you set `index` to `1`, it returns `[1, setIndex]` instead. 4. And so on! -## Giving a component multiple state variables {/*giving-a-component-multiple-state-variables*/} +## Giving a Component multiple state variables {/*giving-a-component-multiple-state-variables*/} -You can have as many state variables of as many types as you like in one component. This component has two state variables, a number `index` and a boolean `showMore` that's toggled when you click "Show details": +You can have as many state variables of as many types as you like in one component. This Component has two state variables, a number `index` and a boolean `showMore` that's toggled when you click "Show details": <Sandpack> @@ -730,9 +730,9 @@ You don't have to understand it to use React, but you might find this a helpful ## State is isolated and private {/*state-is-isolated-and-private*/} -State is local to a component instance on the screen. In other words, **if you render the same component twice, each copy will have completely isolated state!** Changing one of them will not affect the other. +State is local to a Component instance on the screen. In other words, **if you render the same Component twice, each copy will have completely isolated state!** Changing one of them will not affect the other. -In this example, the `Gallery` component from earlier is rendered twice with no changes to its logic. Try clicking the buttons inside each of the galleries. Notice that their state is independent: +In this example, the `Gallery` Component from earlier is rendered twice with no changes to its logic. Try clicking the buttons inside each of the galleries. Notice that their state is independent: <Sandpack> @@ -893,16 +893,16 @@ button { This is what makes state different from regular variables that you might declare at the top of your module. State is not tied to a particular function call or a place in the code, but it's "local" to the specific place on the screen. You rendered two `<Gallery />` components, so their state is stored separately. -Also notice how the `Page` component doesn't "know" anything about the `Gallery` state or even whether it has any. Unlike props, **state is fully private to the component declaring it.** The parent component can't change it. This lets you add state to any component or remove it without impacting the rest of the components. +Also notice how the `Page` Component doesn't "know" anything about the `Gallery` state or even whether it has any. Unlike props, **state is fully private to the Component declaring it.** The parent Component can't change it. This lets you add state to any Component or remove it without impacting the rest of the components. -What if you wanted both galleries to keep their states in sync? The right way to do it in React is to *remove* state from child components and add it to their closest shared parent. The next few pages will focus on organizing state of a single component, but we will return to this topic in [Sharing State Between Components.](/learn/sharing-state-between-components) +What if you wanted both galleries to keep their states in sync? The right way to do it in React is to *remove* state from child Components and add it to their closest shared parent. The next few pages will focus on organizing state of a single component, but we will return to this topic in [Sharing State Between Components.](/learn/sharing-state-between-components) <Recap> -* Use a state variable when a component needs to "remember" some information between renders. +* Use a state variable when a Component needs to "remember" some information between renders. * State variables are declared by calling the `useState` Hook. * Hooks are special functions that start with `use`. They let you "hook into" React features like state. -* Hooks might remind you of imports: they need to be called unconditionally. Calling Hooks, including `useState`, is only valid at the top level of a component or another Hook. +* Hooks might remind you of imports: they need to be called unconditionally. Calling Hooks, including `useState`, is only valid at the top level of a Component or another Hook. * The `useState` Hook returns a pair of values: the current state and the function to update it. * You can have more than one state variable. Internally, React matches them up by their order. * State is private to the component. If you render it in two places, each copy gets its own state. @@ -1331,7 +1331,7 @@ Here is a small form that is supposed to let the user leave some feedback. When <Hint> -Are there any limitations on _where_ Hooks may be called? Does this component break any rules? Check if there are any comments disabling the linter checks--this is where the bugs often hide! +Are there any limitations on _where_ Hooks may be called? Does this Component break any rules? Check if there are any comments disabling the linter checks--this is where the bugs often hide! </Hint> @@ -1370,7 +1370,7 @@ export default function FeedbackForm() { <Solution> -Hooks can only be called at the top level of the component function. Here, the first `isSent` definition follows this rule, but the `message` definition is nested in a condition. +Hooks can only be called at the top level of the Component function. Here, the first `isSent` definition follows this rule, but the `message` definition is nested in a condition. Move it out of the condition to fix the issue: diff --git a/src/content/learn/state-as-a-snapshot.md b/src/content/learn/state-as-a-snapshot.md index df4eddbd677..c626a702553 100644 --- a/src/content/learn/state-as-a-snapshot.md +++ b/src/content/learn/state-as-a-snapshot.md @@ -65,7 +65,7 @@ Here's what happens when you click the button: 1. The `onSubmit` event handler executes. 2. `setIsSent(true)` sets `isSent` to `true` and queues a new render. -3. React re-renders the component according to the new `isSent` value. +3. React re-renders the Component according to the new `isSent` value. Let's take a closer look at the relationship between state and rendering. @@ -87,7 +87,7 @@ When React re-renders a component: <Illustration caption="Updating the DOM tree" src="/images/docs/illustrations/i_render3.png" /> </IllustrationBlock> -As a component's memory, state is not like a regular variable that disappears after your function returns. State actually "lives" in React itself--as if on a shelf!--outside of your function. When React calls your component, it gives you a snapshot of the state for that particular render. Your component returns a snapshot of the UI with a fresh set of props and event handlers in its JSX, all calculated **using the state values from that render!** +As a component's memory, state is not like a regular variable that disappears after your function returns. State actually "lives" in React itself--as if on a shelf!--outside of your function. When React calls your component, it gives you a snapshot of the state for that particular render. Your Component returns a snapshot of the UI with a fresh set of props and event handlers in its JSX, all calculated **using the state values from that render!** <IllustrationBlock sequential> <Illustration caption="You tell React to update the state" src="/images/docs/illustrations/i_state-snapshot1.png" /> @@ -148,7 +148,7 @@ Here is what this button's click handler tells React to do: 3. `setNumber(number + 1)`: `number` is `0` so `setNumber(0 + 1)`. - React prepares to change `number` to `1` on the next render. -Even though you called `setNumber(number + 1)` three times, in *this render's* event handler `number` is always `0`, so you set the state to `1` three times. This is why, after your event handler finishes, React re-renders the component with `number` equal to `1` rather than `3`. +Even though you called `setNumber(number + 1)` three times, in *this render's* event handler `number` is always `0`, so you set the state to `1` three times. This is why, after your event handler finishes, React re-renders the Component with `number` equal to `1` rather than `3`. You can also visualize this by mentally substituting state variables with their values in your code. Since the `number` state variable is `0` for *this render*, its event handler looks like this: @@ -210,7 +210,7 @@ setNumber(0 + 5); alert(0); ``` -But what if you put a timer on the alert, so it only fires _after_ the component re-rendered? Would it say "0" or "5"? Have a guess! +But what if you put a timer on the alert, so it only fires _after_ the Component re-rendered? Would it say "0" or "5"? Have a guess! <Sandpack> @@ -327,7 +327,7 @@ But what if you wanted to read the latest state before a re-render? You'll want #### Implement a traffic light {/*implement-a-traffic-light*/} -Here is a crosswalk light component that toggles when the button is pressed: +Here is a crosswalk light Component that toggles when the button is pressed: <Sandpack> diff --git a/src/content/learn/synchronizing-with-effects.md b/src/content/learn/synchronizing-with-effects.md index f1aa9843849..dd1ab0139d0 100644 --- a/src/content/learn/synchronizing-with-effects.md +++ b/src/content/learn/synchronizing-with-effects.md @@ -4,7 +4,7 @@ title: 'Synchronizing with Effects' <Intro> -Some components need to synchronize with external systems. For example, you might want to control a non-React component based on the React state, set up a server connection, or send an analytics log when a component appears on the screen. *Effects* let you run some code after rendering so that you can synchronize your component with some system outside of React. +Some Components need to synchronize with external systems. For example, you might want to control a non-React Component based on the React state, set up a server connection, or send an analytics log when a Component appears on the screen. *Effects* let you run some code after rendering so that you can synchronize your Component with some system outside of React. </Intro> @@ -24,11 +24,11 @@ Before getting to Effects, you need to be familiar with two types of logic insid - **Rendering code** (introduced in [Describing the UI](/learn/describing-the-ui)) lives at the top level of your component. This is where you take the props and state, transform them, and return the JSX you want to see on the screen. [Rendering code must be pure.](/learn/keeping-components-pure) Like a math formula, it should only _calculate_ the result, but not do anything else. -- **Event handlers** (introduced in [Adding Interactivity](/learn/adding-interactivity)) are nested functions inside your components that *do* things rather than just calculate them. An event handler might update an input field, submit an HTTP POST request to buy a product, or navigate the user to another screen. Event handlers contain ["side effects"](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) (they change the program's state) caused by a specific user action (for example, a button click or typing). +- **Event handlers** (introduced in [Adding Interactivity](/learn/adding-interactivity)) are nested functions inside your Components that *do* things rather than just calculate them. An event handler might update an input field, submit an HTTP POST request to buy a product, or navigate the user to another screen. Event handlers contain ["side effects"](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) (they change the program's state) caused by a specific user action (for example, a button click or typing). -Sometimes this isn't enough. Consider a `ChatRoom` component that must connect to the chat server whenever it's visible on the screen. Connecting to a server is not a pure calculation (it's a side effect) so it can't happen during rendering. However, there is no single particular event like a click that causes `ChatRoom` to be displayed. +Sometimes this isn't enough. Consider a `ChatRoom` Component that must connect to the chat server whenever it's visible on the screen. Connecting to a server is not a pure calculation (it's a side effect) so it can't happen during rendering. However, there is no single particular event like a click that causes `ChatRoom` to be displayed. -***Effects* let you specify side effects that are caused by rendering itself, rather than by a particular event.** Sending a message in the chat is an *event* because it is directly caused by the user clicking a specific button. However, setting up a server connection is an *Effect* because it should happen no matter which interaction caused the component to appear. Effects run at the end of a [commit](/learn/render-and-commit) after the screen updates. This is a good time to synchronize the React components with some external system (like network or a third-party library). +***Effects* let you specify side effects that are caused by rendering itself, rather than by a particular event.** Sending a message in the chat is an *event* because it is directly caused by the user clicking a specific button. However, setting up a server connection is an *Effect* because it should happen no matter which interaction caused the Component to appear. Effects run at the end of a [commit](/learn/render-and-commit) after the screen updates. This is a good time to synchronize the React Components with some external system (like network or a third-party library). <Note> @@ -46,7 +46,7 @@ Here and later in this text, capitalized "Effect" refers to the React-specific d To write an Effect, follow these three steps: 1. **Declare an Effect.** By default, your Effect will run after every render. -2. **Specify the Effect dependencies.** Most Effects should only re-run *when needed* rather than after every render. For example, a fade-in animation should only trigger when a component appears. Connecting and disconnecting to a chat room should only happen when the component appears and disappears, or when the chat room changes. You will learn how to control this by specifying *dependencies.* +2. **Specify the Effect dependencies.** Most Effects should only re-run *when needed* rather than after every render. For example, a fade-in animation should only trigger when a Component appears. Connecting and disconnecting to a chat room should only happen when the Component appears and disappears, or when the chat room changes. You will learn how to control this by specifying *dependencies.* 3. **Add cleanup if needed.** Some Effects need to specify how to stop, undo, or clean up whatever they were doing. For example, "connect" needs "disconnect", "subscribe" needs "unsubscribe", and "fetch" needs either "cancel" or "ignore". You will learn how to do this by returning a *cleanup function*. Let's look at each of these steps in detail. @@ -59,7 +59,7 @@ To declare an Effect in your component, import the [`useEffect` Hook](/reference import { useEffect } from 'react'; ``` -Then, call it at the top level of your component and put some code inside your Effect: +Then, call it at the top level of your Component and put some code inside your Effect: ```js {2-4} function MyComponent() { @@ -70,7 +70,7 @@ function MyComponent() { } ``` -Every time your component renders, React will update the screen *and then* run the code inside `useEffect`. In other words, **`useEffect` "delays" a piece of code from running until that render is reflected on the screen.** +Every time your Component renders, React will update the screen *and then* run the code inside `useEffect`. In other words, **`useEffect` "delays" a piece of code from running until that render is reflected on the screen.** Let's see how you can use an Effect to synchronize with an external system. Consider a `<VideoPlayer>` React component. It would be nice to control whether it's playing or paused by passing an `isPlaying` prop to it: @@ -78,7 +78,7 @@ Let's see how you can use an Effect to synchronize with an external system. Cons <VideoPlayer isPlaying={isPlaying} />; ``` -Your custom `VideoPlayer` component renders the built-in browser [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) tag: +Your custom `VideoPlayer` Component renders the built-in browser [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video) tag: ```js function VideoPlayer({ src, isPlaying }) { @@ -159,7 +159,7 @@ function VideoPlayer({ src, isPlaying }) { By wrapping the DOM update in an Effect, you let React update the screen first. Then your Effect runs. -When your `VideoPlayer` component renders (either the first time or if it re-renders), a few things will happen. First, React will update the screen, ensuring the `<video>` tag is in the DOM with the right props. Then React will run your Effect. Finally, your Effect will call `play()` or `pause()` depending on the value of `isPlaying`. +When your `VideoPlayer` Component renders (either the first time or if it re-renders), a few things will happen. First, React will update the screen, ensuring the `<video>` tag is in the DOM with the right props. Then React will run your Effect. Finally, your Effect will call `play()` or `pause()` depending on the value of `isPlaying`. Press Play/Pause multiple times and see how the video player stays synchronized to the `isPlaying` value: @@ -222,7 +222,7 @@ useEffect(() => { Effects run as a *result* of rendering. Setting state *triggers* rendering. Setting state immediately in an Effect is like plugging a power outlet into itself. The Effect runs, it sets the state, which causes a re-render, which causes the Effect to run, it sets the state again, this causes another re-render, and so on. -Effects should usually synchronize your components with an *external* system. If there's no external system and you only want to adjust some state based on other state, [you might not need an Effect.](/learn/you-might-not-need-an-effect) +Effects should usually synchronize your Components with an *external* system. If there's no external system and you only want to adjust some state based on other state, [you might not need an Effect.](/learn/you-might-not-need-an-effect) </Pitfall> @@ -231,7 +231,7 @@ Effects should usually synchronize your components with an *external* system. If By default, Effects run after *every* render. Often, this is **not what you want:** - Sometimes, it's slow. Synchronizing with an external system is not always instant, so you might want to skip doing it unless it's necessary. For example, you don't want to reconnect to the chat server on every keystroke. -- Sometimes, it's wrong. For example, you don't want to trigger a component fade-in animation on every keystroke. The animation should only play once when the component appears for the first time. +- Sometimes, it's wrong. For example, you don't want to trigger a Component fade-in animation on every keystroke. The animation should only play once when the Component appears for the first time. To demonstrate the issue, here is the previous example with a few `console.log` calls and a text input that updates the parent component's state. Notice how typing causes the Effect to re-run: @@ -411,7 +411,7 @@ useEffect(() => { }); useEffect(() => { - // This runs only on mount (when the component appears) + // This runs only on mount (when the Component appears) }, []); useEffect(() => { @@ -457,13 +457,13 @@ function VideoPlayer({ src, isPlaying }) { The [`set` functions](/reference/react/useState#setstate) returned by `useState` also have stable identity, so you will often see them omitted from the dependencies too. If the linter lets you omit a dependency without errors, it is safe to do. -Omitting always-stable dependencies only works when the linter can "see" that the object is stable. For example, if `ref` was passed from a parent component, you would have to specify it in the dependency array. However, this is good because you can't know whether the parent component always passes the same ref, or passes one of several refs conditionally. So your Effect _would_ depend on which ref is passed. +Omitting always-stable dependencies only works when the linter can "see" that the object is stable. For example, if `ref` was passed from a parent component, you would have to specify it in the dependency array. However, this is good because you can't know whether the parent Component always passes the same ref, or passes one of several refs conditionally. So your Effect _would_ depend on which ref is passed. </DeepDive> ### Step 3: Add cleanup if needed {/*step-3-add-cleanup-if-needed*/} -Consider a different example. You're writing a `ChatRoom` component that needs to connect to the chat server when it appears. You are given a `createConnection()` API that returns an object with `connect()` and `disconnect()` methods. How do you keep the component connected while it is displayed to the user? +Consider a different example. You're writing a `ChatRoom` Component that needs to connect to the chat server when it appears. You are given a `createConnection()` API that returns an object with `connect()` and `disconnect()` methods. How do you keep the Component connected while it is displayed to the user? Start by writing the Effect logic: @@ -483,7 +483,7 @@ useEffect(() => { }, []); ``` -**The code inside the Effect does not use any props or state, so your dependency array is `[]` (empty). This tells React to only run this code when the component "mounts", i.e. appears on the screen for the first time.** +**The code inside the Effect does not use any props or state, so your dependency array is `[]` (empty). This tells React to only run this code when the Component "mounts", i.e. appears on the screen for the first time.** Let's try running this code: @@ -524,11 +524,11 @@ input { display: block; margin-bottom: 20px; } This Effect only runs on mount, so you might expect `"✅ Connecting..."` to be printed once in the console. **However, if you check the console, `"✅ Connecting..."` gets printed twice. Why does it happen?** -Imagine the `ChatRoom` component is a part of a larger app with many different screens. The user starts their journey on the `ChatRoom` page. The component mounts and calls `connection.connect()`. Then imagine the user navigates to another screen--for example, to the Settings page. The `ChatRoom` component unmounts. Finally, the user clicks Back and `ChatRoom` mounts again. This would set up a second connection--but the first connection was never destroyed! As the user navigates across the app, the connections would keep piling up. +Imagine the `ChatRoom` Component is a part of a larger app with many different screens. The user starts their journey on the `ChatRoom` page. The Component mounts and calls `connection.connect()`. Then imagine the user navigates to another screen--for example, to the Settings page. The `ChatRoom` Component unmounts. Finally, the user clicks Back and `ChatRoom` mounts again. This would set up a second connection--but the first connection was never destroyed! As the user navigates across the app, the connections would keep piling up. -Bugs like this are easy to miss without extensive manual testing. To help you spot them quickly, in development React remounts every component once immediately after its initial mount. +Bugs like this are easy to miss without extensive manual testing. To help you spot them quickly, in development React remounts every Component once immediately after its initial mount. -Seeing the `"✅ Connecting..."` log twice helps you notice the real issue: your code doesn't close the connection when the component unmounts. +Seeing the `"✅ Connecting..."` log twice helps you notice the real issue: your code doesn't close the connection when the Component unmounts. To fix the issue, return a *cleanup function* from your Effect: @@ -542,7 +542,7 @@ To fix the issue, return a *cleanup function* from your Effect: }, []); ``` -React will call your cleanup function each time before the Effect runs again, and one final time when the component unmounts (gets removed). Let's see what happens when the cleanup function is implemented: +React will call your cleanup function each time before the Effect runs again, and one final time when the Component unmounts (gets removed). Let's see what happens when the cleanup function is implemented: <Sandpack> @@ -588,11 +588,11 @@ Now you get three console logs in development: **This is the correct behavior in development.** By remounting your component, React verifies that navigating away and back would not break your code. Disconnecting and then connecting again is exactly what should happen! When you implement the cleanup well, there should be no user-visible difference between running the Effect once vs running it, cleaning it up, and running it again. There's an extra connect/disconnect call pair because React is probing your code for bugs in development. This is normal--don't try to make it go away! -**In production, you would only see `"✅ Connecting..."` printed once.** Remounting components only happens in development to help you find Effects that need cleanup. You can turn off [Strict Mode](/reference/react/StrictMode) to opt out of the development behavior, but we recommend keeping it on. This lets you find many bugs like the one above. +**In production, you would only see `"✅ Connecting..."` printed once.** Remounting Components only happens in development to help you find Effects that need cleanup. You can turn off [Strict Mode](/reference/react/StrictMode) to opt out of the development behavior, but we recommend keeping it on. This lets you find many bugs like the one above. ## How to handle the Effect firing twice in development? {/*how-to-handle-the-effect-firing-twice-in-development*/} -React intentionally remounts your components in development to find bugs like in the last example. **The right question isn't "how to run an Effect once", but "how to fix my Effect so that it works after remounting".** +React intentionally remounts your Components in development to find bugs like in the last example. **The right question isn't "how to run an Effect once", but "how to fix my Effect so that it works after remounting".** Usually, the answer is to implement the cleanup function. The cleanup function should stop or undo whatever the Effect was doing. The rule of thumb is that the user shouldn't be able to distinguish between the Effect running once (as in production) and a _setup → cleanup → setup_ sequence (as you'd see in development). @@ -600,7 +600,7 @@ Most of the Effects you'll write will fit into one of the common patterns below. ### Controlling non-React widgets {/*controlling-non-react-widgets*/} -Sometimes you need to add UI widgets that aren't written to React. For example, let's say you're adding a map component to your page. It has a `setZoomLevel()` method, and you'd like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this: +Sometimes you need to add UI widgets that aren't written to React. For example, let's say you're adding a map Component to your page. It has a `setZoomLevel()` method, and you'd like to keep the zoom level in sync with a `zoomLevel` state variable in your React code. Your Effect would look similar to this: ```js useEffect(() => { @@ -700,7 +700,7 @@ Writing `fetch` calls inside Effects is a [popular way to fetch data](https://ww - **Effects don't run on the server.** This means that the initial server-rendered HTML will only include a loading state with no data. The client computer will have to download all JavaScript and render your app only to discover that now it needs to load the data. This is not very efficient. - **Fetching directly in Effects makes it easy to create "network waterfalls".** You render the parent component, it fetches some data, renders the child components, and then they start fetching their data. If the network is not very fast, this is significantly slower than fetching all data in parallel. -- **Fetching directly in Effects usually means you don't preload or cache data.** For example, if the component unmounts and then mounts again, it would have to fetch the data again. +- **Fetching directly in Effects usually means you don't preload or cache data.** For example, if the Component unmounts and then mounts again, it would have to fetch the data again. - **It's not very ergonomic.** There's quite a bit of boilerplate code involved when writing `fetch` calls in a way that doesn't suffer from bugs like [race conditions.](https://maxrozen.com/race-conditions-fetching-data-react-with-useeffect) This list of downsides is not specific to React. It applies to fetching data on mount with any library. Like with routing, data fetching is not trivial to do well, so we recommend the following approaches: @@ -722,11 +722,11 @@ useEffect(() => { }, [url]); ``` -In development, `logVisit` will be called twice for every URL, so you might be tempted to try to fix that. **We recommend keeping this code as is.** Like with earlier examples, there is no *user-visible* behavior difference between running it once and running it twice. From a practical point of view, `logVisit` should not do anything in development because you don't want the logs from the development machines to skew the production metrics. Your component remounts every time you save its file, so it logs extra visits in development anyway. +In development, `logVisit` will be called twice for every URL, so you might be tempted to try to fix that. **We recommend keeping this code as is.** Like with earlier examples, there is no *user-visible* behavior difference between running it once and running it twice. From a practical point of view, `logVisit` should not do anything in development because you don't want the logs from the development machines to skew the production metrics. Your Component remounts every time you save its file, so it logs extra visits in development anyway. **In production, there will be no duplicate visit logs.** -To debug the analytics events you're sending, you can deploy your app to a staging environment (which runs in production mode) or temporarily opt out of [Strict Mode](/reference/react/StrictMode) and its development-only remounting checks. You may also send analytics from the route change event handlers instead of Effects. For more precise analytics, [intersection observers](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) can help track which components are in the viewport and how long they remain visible. +To debug the analytics events you're sending, you can deploy your app to a staging environment (which runs in production mode) or temporarily opt out of [Strict Mode](/reference/react/StrictMode) and its development-only remounting checks. You may also send analytics from the route change event handlers instead of Effects. For more precise analytics, [intersection observers](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) can help track which Components are in the viewport and how long they remain visible. ### Not an Effect: Initializing the application {/*not-an-effect-initializing-the-application*/} @@ -767,7 +767,7 @@ Buying is not caused by rendering; it's caused by a specific interaction. It sho } ``` -**This illustrates that if remounting breaks the logic of your application, this usually uncovers existing bugs.** From a user's perspective, visiting a page shouldn't be different from visiting it, clicking a link, then pressing Back to view the page again. React verifies that your components abide by this principle by remounting them once in development. +**This illustrates that if remounting breaks the logic of your application, this usually uncovers existing bugs.** From a user's perspective, visiting a page shouldn't be different from visiting it, clicking a link, then pressing Back to view the page again. React verifies that your Components abide by this principle by remounting them once in development. ## Putting it all together {/*putting-it-all-together*/} @@ -827,13 +827,13 @@ export default function App() { </Sandpack> -You will see three logs at first: `Schedule "a" log`, `Cancel "a" log`, and `Schedule "a" log` again. Three second later there will also be a log saying `a`. As you learned earlier, the extra schedule/cancel pair is because React remounts the component once in development to verify that you've implemented cleanup well. +You will see three logs at first: `Schedule "a" log`, `Cancel "a" log`, and `Schedule "a" log` again. Three second later there will also be a log saying `a`. As you learned earlier, the extra schedule/cancel pair is because React remounts the Component once in development to verify that you've implemented cleanup well. Now edit the input to say `abc`. If you do it fast enough, you'll see `Schedule "ab" log` immediately followed by `Cancel "ab" log` and `Schedule "abc" log`. **React always cleans up the previous render's Effect before the next render's Effect.** This is why even if you type into the input fast, there is at most one timeout scheduled at a time. Edit the input a few times and watch the console to get a feel for how Effects get cleaned up. Type something into the input and then immediately press "Unmount the component". Notice how unmounting cleans up the last render's Effect. Here, it clears the last timeout before it has a chance to fire. -Finally, edit the component above and comment out the cleanup function so that the timeouts don't get cancelled. Try typing `abcde` fast. What do you expect to happen in three seconds? Will `console.log(text)` inside the timeout print the *latest* `text` and produce five `abcde` logs? Give it a try to check your intuition! +Finally, edit the Component above and comment out the cleanup function so that the timeouts don't get cancelled. Try typing `abcde` fast. What do you expect to happen in three seconds? Will `console.log(text)` inside the timeout print the *latest* `text` and produce five `abcde` logs? Give it a try to check your intuition! Three seconds later, you should see a sequence of logs (`a`, `ab`, `abc`, `abcd`, and `abcde`) rather than five `abcde` logs. **Each Effect "captures" the `text` value from its corresponding render.** It doesn't matter that the `text` state changed: an Effect from the render with `text = 'ab'` will always see `'ab'`. In other words, Effects from each render are isolated from each other. If you're curious how this works, you can read about [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). @@ -909,7 +909,7 @@ React compares `['general']` from the second render with `['general']` from the #### Re-render with different dependencies {/*re-render-with-different-dependencies*/} -Then, the user visits `<ChatRoom roomId="travel" />`. This time, the component returns different JSX: +Then, the user visits `<ChatRoom roomId="travel" />`. This time, the Component returns different JSX: ```js // JSX for the third render (roomId = "travel") @@ -939,23 +939,23 @@ After that, React runs the third render's Effect. It connects to the `'travel'` #### Unmount {/*unmount*/} -Finally, let's say the user navigates away, and the `ChatRoom` component unmounts. React runs the last Effect's cleanup function. The last Effect was from the third render. The third render's cleanup destroys the `createConnection('travel')` connection. So the app disconnects from the `'travel'` room. +Finally, let's say the user navigates away, and the `ChatRoom` Component unmounts. React runs the last Effect's cleanup function. The last Effect was from the third render. The third render's cleanup destroys the `createConnection('travel')` connection. So the app disconnects from the `'travel'` room. #### Development-only behaviors {/*development-only-behaviors*/} -When [Strict Mode](/reference/react/StrictMode) is on, React remounts every component once after mount (state and DOM are preserved). This [helps you find Effects that need cleanup](#step-3-add-cleanup-if-needed) and exposes bugs like race conditions early. Additionally, React will remount the Effects whenever you save a file in development. Both of these behaviors are development-only. +When [Strict Mode](/reference/react/StrictMode) is on, React remounts every Component once after mount (state and DOM are preserved). This [helps you find Effects that need cleanup](#step-3-add-cleanup-if-needed) and exposes bugs like race conditions early. Additionally, React will remount the Effects whenever you save a file in development. Both of these behaviors are development-only. </DeepDive> <Recap> - Unlike events, Effects are caused by rendering itself rather than a particular interaction. -- Effects let you synchronize a component with some external system (third-party API, network, etc). +- Effects let you synchronize a Component with some external system (third-party API, network, etc). - By default, Effects run after every render (including the initial one). - React will skip the Effect if all of its dependencies have the same values as during the last render. - You can't "choose" your dependencies. They are determined by the code inside the Effect. -- Empty dependency array (`[]`) corresponds to the component "mounting", i.e. being added to the screen. -- In Strict Mode, React mounts components twice (in development only!) to stress-test your Effects. +- Empty dependency array (`[]`) corresponds to the Component "mounting", i.e. being added to the screen. +- In Strict Mode, React mounts Components twice (in development only!) to stress-test your Effects. - If your Effect breaks because of remounting, you need to implement a cleanup function. - React will call your cleanup function before the Effect runs next time, and during the unmount. @@ -1049,7 +1049,7 @@ To verify that your solution works, press "Show form" and verify that the input <Solution> -Calling `ref.current.focus()` during render is wrong because it is a *side effect*. Side effects should either be placed inside an event handler or be declared with `useEffect`. In this case, the side effect is _caused_ by the component appearing rather than by any specific interaction, so it makes sense to put it in an Effect. +Calling `ref.current.focus()` during render is wrong because it is a *side effect*. Side effects should either be placed inside an event handler or be declared with `useEffect`. In this case, the side effect is _caused_ by the Component appearing rather than by any specific interaction, so it makes sense to put it in an Effect. To fix the mistake, wrap the `ref.current.focus()` call into an Effect declaration. Then, to ensure that this Effect runs only on mount rather than after every render, add the empty `[]` dependencies to it. @@ -1133,9 +1133,9 @@ body { This form renders two `<MyInput />` components. -Press "Show form" and notice that the second field automatically gets focused. This is because both of the `<MyInput />` components try to focus the field inside. When you call `focus()` for two input fields in a row, the last one always "wins". +Press "Show form" and notice that the second field automatically gets focused. This is because both of the `<MyInput />` Components try to focus the field inside. When you call `focus()` for two input fields in a row, the last one always "wins". -Let's say you want to focus the first field. The first `MyInput` component now receives a boolean `shouldFocus` prop set to `true`. Change the logic so that `focus()` is only called if the `shouldFocus` prop received by `MyInput` is `true`. +Let's say you want to focus the first field. The first `MyInput` Component now receives a boolean `shouldFocus` prop set to `true`. Change the logic so that `focus()` is only called if the `shouldFocus` prop received by `MyInput` is `true`. <Sandpack> @@ -1215,7 +1215,7 @@ body { </Sandpack> -To verify your solution, press "Show form" and "Hide form" repeatedly. When the form appears, only the *first* input should get focused. This is because the parent component renders the first input with `shouldFocus={true}` and the second input with `shouldFocus={false}`. Also check that both inputs still work and you can type into both of them. +To verify your solution, press "Show form" and "Hide form" repeatedly. When the form appears, only the *first* input should get focused. This is because the parent Component renders the first input with `shouldFocus={true}` and the second input with `shouldFocus={false}`. Also check that both inputs still work and you can type into both of them. <Hint> @@ -1310,7 +1310,7 @@ body { #### Fix an interval that fires twice {/*fix-an-interval-that-fires-twice*/} -This `Counter` component displays a counter that should increment every second. On mount, it calls [`setInterval`.](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) This causes `onTick` to run every second. The `onTick` function increments the counter. +This `Counter` Component displays a counter that should increment every second. On mount, it calls [`setInterval`.](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) This causes `onTick` to run every second. The `onTick` function increments the counter. However, instead of incrementing once per second, it increments twice. Why is that? Find the cause of the bug and fix it. @@ -1373,7 +1373,7 @@ body { <Solution> -When [Strict Mode](/reference/react/StrictMode) is on (like in the sandboxes on this site), React remounts each component once in development. This causes the interval to be set up twice, and this is why each second the counter increments twice. +When [Strict Mode](/reference/react/StrictMode) is on (like in the sandboxes on this site), React remounts each Component once in development. This causes the interval to be set up twice, and this is why each second the counter increments twice. However, React's behavior is not the *cause* of the bug: the bug already exists in the code. React's behavior makes the bug more noticeable. The real cause is that this Effect starts a process but doesn't provide a way to clean it up. @@ -1431,13 +1431,13 @@ body { </Sandpack> -In development, React will still remount your component once to verify that you've implemented cleanup well. So there will be a `setInterval` call, immediately followed by `clearInterval`, and `setInterval` again. In production, there will be only one `setInterval` call. The user-visible behavior in both cases is the same: the counter increments once per second. +In development, React will still remount your Component once to verify that you've implemented cleanup well. So there will be a `setInterval` call, immediately followed by `clearInterval`, and `setInterval` again. In production, there will be only one `setInterval` call. The user-visible behavior in both cases is the same: the counter increments once per second. </Solution> #### Fix fetching inside an Effect {/*fix-fetching-inside-an-effect*/} -This component shows the biography for the selected person. It loads the biography by calling an asynchronous function `fetchBio(person)` on mount and whenever `person` changes. That asynchronous function returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which eventually resolves to a string. When fetching is done, it calls `setBio` to display that string under the select box. +This Component shows the biography for the selected person. It loads the biography by calling an asynchronous function `fetchBio(person)` on mount and whenever `person` changes. That asynchronous function returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which eventually resolves to a string. When fetching is done, it calls `setBio` to display that string under the select box. <Sandpack> diff --git a/src/content/learn/thinking-in-react.md b/src/content/learn/thinking-in-react.md index 0f05a0569f6..2103061fbfd 100644 --- a/src/content/learn/thinking-in-react.md +++ b/src/content/learn/thinking-in-react.md @@ -4,7 +4,7 @@ title: Thinking in React <Intro> -React can change how you think about the designs you look at and the apps you build. When you build a user interface with React, you will first break it apart into pieces called *components*. Then, you will describe the different visual states for each of your components. Finally, you will connect your components together so that the data flows through them. In this tutorial, we’ll guide you through the thought process of building a searchable product data table with React. +React can change how you think about the designs you look at and the apps you build. When you build a user interface with React, you will first break it apart into pieces called *components*. Then, you will describe the different visual states for each of your components. Finally, you will connect your Components together so that the data flows through them. In this tutorial, we’ll guide you through the thought process of building a searchable product data table with React. </Intro> @@ -31,19 +31,19 @@ The mockup looks like this: To implement a UI in React, you will usually follow the same five steps. -## Step 1: Break the UI into a component hierarchy {/*step-1-break-the-ui-into-a-component-hierarchy*/} +## Step 1: Break the UI into a Component hierarchy {/*step-1-break-the-ui-into-a-component-hierarchy*/} -Start by drawing boxes around every component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these components in their design tool. Ask them! +Start by drawing boxes around every Component and subcomponent in the mockup and naming them. If you work with a designer, they may have already named these Components in their design tool. Ask them! -Depending on your background, you can think about splitting up a design into components in different ways: +Depending on your background, you can think about splitting up a design into Components in different ways: -* **Programming**--use the same techniques for deciding if you should create a new function or object. One such technique is the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), that is, a component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents. -* **CSS**--consider what you would make class selectors for. (However, components are a bit less granular.) +* **Programming**--use the same techniques for deciding if you should create a new function or object. One such technique is the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle), that is, a Component should ideally only do one thing. If it ends up growing, it should be decomposed into smaller subcomponents. +* **CSS**--consider what you would make class selectors for. (However, Components are a bit less granular.) * **Design**--consider how you would organize the design's layers. -If your JSON is well-structured, you'll often find that it naturally maps to the component structure of your UI. That's because UI and data models often have the same information architecture--that is, the same shape. Separate your UI into components, where each component matches one piece of your data model. +If your JSON is well-structured, you'll often find that it naturally maps to the Component structure of your UI. That's because UI and data models often have the same information architecture--that is, the same shape. Separate your UI into components, where each Component matches one piece of your data model. -There are five components on this screen: +There are five Components on this screen: <FullWidth> @@ -63,7 +63,7 @@ There are five components on this screen: If you look at `ProductTable` (lavender), you'll see that the table header (containing the "Name" and "Price" labels) isn't its own component. This is a matter of preference, and you could go either way. For this example, it is a part of `ProductTable` because it appears inside the `ProductTable`'s list. However, if this header grows to be complex (e.g., if you add sorting), you can move it into its own `ProductTableHeader` component. -Now that you've identified the components in the mockup, arrange them into a hierarchy. Components that appear within another component in the mockup should appear as a child in the hierarchy: +Now that you've identified the Components in the mockup, arrange them into a hierarchy. Components that appear within another Component in the mockup should appear as a child in the hierarchy: * `FilterableProductTable` * `SearchBar` @@ -73,11 +73,11 @@ Now that you've identified the components in the mockup, arrange them into a hie ## Step 2: Build a static version in React {/*step-2-build-a-static-version-in-react*/} -Now that you have your component hierarchy, it's time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity... yet! It's often easier to build the static version first and add interactivity later. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing. +Now that you have your Component hierarchy, it's time to implement your app. The most straightforward approach is to build a version that renders the UI from your data model without adding any interactivity... yet! It's often easier to build the static version first and add interactivity later. Building a static version requires a lot of typing and no thinking, but adding interactivity requires a lot of thinking and not a lot of typing. -To build a static version of your app that renders your data model, you'll want to build [components](/learn/your-first-component) that reuse other components and pass data using [props.](/learn/passing-props-to-a-component) Props are a way of passing data from parent to child. (If you're familiar with the concept of [state](/learn/state-a-components-memory), don't use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don't need it.) +To build a static version of your app that renders your data model, you'll want to build [components](/learn/your-first-component) that reuse other Components and pass data using [props.](/learn/passing-props-to-a-component) Props are a way of passing data from parent to child. (If you're familiar with the concept of [state](/learn/state-a-components-memory), don't use state at all to build this static version. State is reserved only for interactivity, that is, data that changes over time. Since this is a static version of the app, you don't need it.) -You can either build "top down" by starting with building the components higher up in the hierarchy (like `FilterableProductTable`) or "bottom up" by working from components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up. +You can either build "top down" by starting with building the Components higher up in the hierarchy (like `FilterableProductTable`) or "bottom up" by working from Components lower down (like `ProductRow`). In simpler examples, it’s usually easier to go top-down, and on larger projects, it’s easier to go bottom-up. <Sandpack> @@ -197,7 +197,7 @@ td { (If this code looks intimidating, go through the [Quick Start](/learn/) first!) -After building your components, you'll have a library of reusable components that render your data model. Because this is a static app, the components will only return JSX. The component at the top of the hierarchy (`FilterableProductTable`) will take your data model as a prop. This is called _one-way data flow_ because the data flows down from the top-level component to the ones at the bottom of the tree. +After building your components, you'll have a library of reusable Components that render your data model. Because this is a static app, the Components will only return JSX. The Component at the top of the hierarchy (`FilterableProductTable`) will take your data model as a prop. This is called _one-way data flow_ because the data flows down from the top-level Component to the ones at the bottom of the tree. <Pitfall> @@ -241,39 +241,39 @@ This means only the search text and the value of the checkbox are state! Nicely There are two types of "model" data in React: props and state. The two are very different: -* [**Props** are like arguments you pass](/learn/passing-props-to-a-component) to a function. They let a parent component pass data to a child component and customize its appearance. For example, a `Form` can pass a `color` prop to a `Button`. -* [**State** is like a component’s memory.](/learn/state-a-components-memory) It lets a component keep track of some information and change it in response to interactions. For example, a `Button` might keep track of `isHovered` state. +* [**Props** are like arguments you pass](/learn/passing-props-to-a-component) to a function. They let a parent Component pass data to a child Component and customize its appearance. For example, a `Form` can pass a `color` prop to a `Button`. +* [**State** is like a component’s memory.](/learn/state-a-components-memory) It lets a Component keep track of some information and change it in response to interactions. For example, a `Button` might keep track of `isHovered` state. -Props and state are different, but they work together. A parent component will often keep some information in state (so that it can change it), and *pass it down* to child components as their props. It's okay if the difference still feels fuzzy on the first read. It takes a bit of practice for it to really stick! +Props and state are different, but they work together. A parent Component will often keep some information in state (so that it can change it), and *pass it down* to child Components as their props. It's okay if the difference still feels fuzzy on the first read. It takes a bit of practice for it to really stick! </DeepDive> ## Step 4: Identify where your state should live {/*step-4-identify-where-your-state-should-live*/} -After identifying your app’s minimal state data, you need to identify which component is responsible for changing this state, or *owns* the state. Remember: React uses one-way data flow, passing data down the component hierarchy from parent to child component. It may not be immediately clear which component should own what state. This can be challenging if you’re new to this concept, but you can figure it out by following these steps! +After identifying your app’s minimal state data, you need to identify which Component is responsible for changing this state, or *owns* the state. Remember: React uses one-way data flow, passing data down the Component hierarchy from parent to child component. It may not be immediately clear which Component should own what state. This can be challenging if you’re new to this concept, but you can figure it out by following these steps! For each piece of state in your application: -1. Identify *every* component that renders something based on that state. -2. Find their closest common parent component--a component above them all in the hierarchy. +1. Identify *every* Component that renders something based on that state. +2. Find their closest common parent component--a Component above them all in the hierarchy. 3. Decide where the state should live: 1. Often, you can put the state directly into their common parent. - 2. You can also put the state into some component above their common parent. - 3. If you can't find a component where it makes sense to own the state, create a new component solely for holding the state and add it somewhere in the hierarchy above the common parent component. + 2. You can also put the state into some Component above their common parent. + 3. If you can't find a Component where it makes sense to own the state, create a new Component solely for holding the state and add it somewhere in the hierarchy above the common parent component. In the previous step, you found two pieces of state in this application: the search input text, and the value of the checkbox. In this example, they always appear together, so it makes sense to put them into the same place. Now let's run through our strategy for them: -1. **Identify components that use state:** +1. **Identify Components that use state:** * `ProductTable` needs to filter the product list based on that state (search text and checkbox value). * `SearchBar` needs to display that state (search text and checkbox value). -1. **Find their common parent:** The first parent component both components share is `FilterableProductTable`. +1. **Find their common parent:** The first parent Component both Components share is `FilterableProductTable`. 2. **Decide where the state lives**: We'll keep the filter text and checked state values in `FilterableProductTable`. So the state values will live in `FilterableProductTable`. -Add state to the component with the [`useState()` Hook.](/reference/react/useState) Hooks are special functions that let you "hook into" React. Add two state variables at the top of `FilterableProductTable` and specify their initial state: +Add state to the Component with the [`useState()` Hook.](/reference/react/useState) Hooks are special functions that let you "hook into" React. Add two state variables at the top of `FilterableProductTable` and specify their initial state: ```js function FilterableProductTable({ products }) { @@ -462,7 +462,7 @@ However, you haven't added any code to respond to the user actions like typing y ## Step 5: Add inverse data flow {/*step-5-add-inverse-data-flow*/} -Currently your app renders correctly with props and state flowing down the hierarchy. But to change the state according to user input, you will need to support data flowing the other way: the form components deep in the hierarchy need to update the state in `FilterableProductTable`. +Currently your app renders correctly with props and state flowing down the hierarchy. But to change the state according to user input, you will need to support data flowing the other way: the form Components deep in the hierarchy need to update the state in `FilterableProductTable`. React makes this data flow explicit, but it requires a little more typing than two-way data binding. If you try to type or check the box in the example above, you'll see that React ignores your input. This is intentional. By writing `<input value={filterText} />`, you've set the `value` prop of the `input` to always be equal to the `filterText` state passed in from `FilterableProductTable`. Since `filterText` state is never set, the input never changes. @@ -660,4 +660,4 @@ You can learn all about handling events and updating state in the [Adding Intera ## Where to go from here {/*where-to-go-from-here*/} -This was a very brief introduction to how to think about building components and applications with React. You can [start a React project](/learn/installation) right now or [dive deeper on all the syntax](/learn/describing-the-ui) used in this tutorial. +This was a very brief introduction to how to think about building Components and applications with React. You can [start a React project](/learn/installation) right now or [dive deeper on all the syntax](/learn/describing-the-ui) used in this tutorial. diff --git a/src/content/learn/tutorial-tic-tac-toe.md b/src/content/learn/tutorial-tic-tac-toe.md index d3779145685..f7e97268ee1 100644 --- a/src/content/learn/tutorial-tic-tac-toe.md +++ b/src/content/learn/tutorial-tic-tac-toe.md @@ -303,7 +303,7 @@ Now let's have a look at the files in the starter code. #### `App.js` {/*appjs*/} -The code in `App.js` creates a _component_. In React, a component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let's look at the component line by line to see what's going on: +The code in `App.js` creates a _component_. In React, a Component is a piece of reusable code that represents a part of a user interface. Components are used to render, manage, and update the UI elements in your application. Let's look at the Component line by line to see what's going on: ```js {1} export default function Square() { @@ -323,11 +323,11 @@ The second line returns a button. The `return` JavaScript keyword means whatever #### `styles.css` {/*stylescss*/} -Click on the file labeled `styles.css` in the _Files_ section of CodeSandbox. This file defines the styles for your React app. The first two _CSS selectors_ (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any component where the `className` property is set to `square`. In your code, that would match the button from your Square component in the `App.js` file. +Click on the file labeled `styles.css` in the _Files_ section of CodeSandbox. This file defines the styles for your React app. The first two _CSS selectors_ (`*` and `body`) define the style of large parts of your app while the `.square` selector defines the style of any Component where the `className` property is set to `square`. In your code, that would match the button from your Square Component in the `App.js` file. #### `index.js` {/*indexjs*/} -Click on the file labeled `index.js` in the _Files_ section of CodeSandbox. You won't be editing this file during the tutorial but it is the bridge between the component you created in the `App.js` file and the web browser. +Click on the file labeled `index.js` in the _Files_ section of CodeSandbox. You won't be editing this file during the tutorial but it is the bridge between the Component you created in the `App.js` file and the web browser. ```jsx import { StrictMode } from 'react'; @@ -342,7 +342,7 @@ Lines 1-5 bring all the necessary pieces together: * React * React's library to talk to web browsers (React DOM) * the styles for your components -* the component you created in `App.js`. +* the Component you created in `App.js`. The remainder of the file brings all the pieces together and injects the final product into `index.html` in the `public` folder. @@ -366,7 +366,7 @@ You'll get this error: </ConsoleBlock> -React components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *Fragments* (`<>` and `</>`) to wrap multiple adjacent JSX elements like this: +React Components need to return a single JSX element and not multiple adjacent JSX elements like two buttons. To fix this you can use *Fragments* (`<>` and `</>`) to wrap multiple adjacent JSX elements like this: ```js {3-6} export default function Square() { @@ -389,7 +389,7 @@ Great! Now you just need to copy-paste a few times to add nine squares and... Oh no! The squares are all in a single line, not in a grid like you need for our board. To fix this you'll need to group your squares into rows with `div`s and add some CSS classes. While you're at it, you'll give each square a number to make sure you know where each square is displayed. -In the `App.js` file, update the `Square` component to look like this: +In the `App.js` file, update the `Square` Component to look like this: ```js {3-19} export default function Square() { @@ -415,11 +415,11 @@ export default function Square() { } ``` -The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you've grouped your components into rows with the styled `div`s you have your tic-tac-toe board: +The CSS defined in `styles.css` styles the divs with the `className` of `board-row`. Now that you've grouped your Components into rows with the styled `div`s you have your tic-tac-toe board: ![tic-tac-toe board filled with numbers 1 through 9](../images/tutorial/number-filled-board.png) -But you now have a problem. Your component named `Square`, really isn't a square anymore. Let's fix that by changing the name to `Board`: +But you now have a problem. Your Component named `Square`, really isn't a square anymore. Let's fix that by changing the name to `Board`: ```js {1} export default function Board() { @@ -510,9 +510,9 @@ Psssst... That's a lot to type! It's okay to copy and paste code from this page. ### Passing data through props {/*passing-data-through-props*/} -Next, you'll want to change the value of a square from empty to "X" when the user clicks on the square. With how you've built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React's component architecture allows you to create a reusable component to avoid messy, duplicated code. +Next, you'll want to change the value of a square from empty to "X" when the user clicks on the square. With how you've built the board so far you would need to copy-paste the code that updates the square nine times (once for each square you have)! Instead of copy-pasting, React's Component architecture allows you to create a reusable Component to avoid messy, duplicated code. -First, you are going to copy the line defining your first square (`<button className="square">1</button>`) from your `Board` component into a new `Square` component: +First, you are going to copy the line defining your first square (`<button className="square">1</button>`) from your `Board` Component into a new `Square` component: ```js {1-3} function Square() { @@ -524,7 +524,7 @@ export default function Board() { } ``` -Then you'll update the Board component to render that `Square` component using JSX syntax: +Then you'll update the Board Component to render that `Square` Component using JSX syntax: ```js {5-19} // ... @@ -551,15 +551,15 @@ export default function Board() { } ``` -Note how unlike the browser `div`s, your own components `Board` and `Square` must start with a capital letter. +Note how unlike the browser `div`s, your own Components `Board` and `Square` must start with a capital letter. Let's take a look: ![one-filled board](../images/tutorial/board-filled-with-ones.png) -Oh no! You lost the numbered squares you had before. Now each square says "1". To fix this, you will use *props* to pass the value each square should have from the parent component (`Board`) to its child (`Square`). +Oh no! You lost the numbered squares you had before. Now each square says "1". To fix this, you will use *props* to pass the value each square should have from the parent Component (`Board`) to its child (`Square`). -Update the `Square` component to read the `value` prop that you'll pass from the `Board`: +Update the `Square` Component to read the `value` prop that you'll pass from the `Board`: ```js {1} function Square({ value }) { @@ -567,7 +567,7 @@ function Square({ value }) { } ``` -`function Square({ value })` indicates the Square component can be passed a prop called `value`. +`function Square({ value })` indicates the Square Component can be passed a prop called `value`. Now you want to display that `value` instead of `1` inside every square. Try doing it like this: @@ -593,7 +593,7 @@ For now, you should see an empty board: ![empty board](../images/tutorial/empty-board.png) -This is because the `Board` component hasn't passed the `value` prop to each `Square` component it renders yet. To fix it you'll add the `value` prop to each `Square` component rendered by the `Board` component: +This is because the `Board` Component hasn't passed the `value` prop to each `Square` Component it renders yet. To fix it you'll add the `value` prop to each `Square` Component rendered by the `Board` component: ```js {5-7,10-12,15-17} export default function Board() { @@ -702,9 +702,9 @@ body { </Sandpack> -### Making an interactive component {/*making-an-interactive-component*/} +### Making an interactive Component {/*making-an-interactive-component*/} -Let's fill the `Square` component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`: +Let's fill the `Square` Component with an `X` when you click it. Declare a function called `handleClick` inside of the `Square`. Then, add `onClick` to the props of the button JSX element returned from the `Square`: ```js {2-4,9} function Square({ value }) { @@ -731,9 +731,9 @@ If you are following this tutorial using your local development environment, you </Note> -As a next step, you want the Square component to "remember" that it got clicked, and fill it with an "X" mark. To "remember" things, components use *state*. +As a next step, you want the Square Component to "remember" that it got clicked, and fill it with an "X" mark. To "remember" things, Components use *state*. -React provides a special function called `useState` that you can call from your component to let it "remember" things. Let's store the current value of the `Square` in state, and change it when the `Square` is clicked. +React provides a special function called `useState` that you can call from your Component to let it "remember" things. Let's store the current value of the `Square` in state, and change it when the `Square` is clicked. Import `useState` at the top of the file. Remove the `value` prop from the `Square` component. Instead, add a new line at the start of the `Square` that calls `useState`. Have it return a state variable called `value`: @@ -749,7 +749,7 @@ function Square() { `value` stores the value and `setValue` is a function that can be used to change the value. The `null` passed to `useState` is used as the initial value for this state variable, so `value` here starts off equal to `null`. -Since the `Square` component no longer accepts props anymore, you'll remove the `value` prop from all nine of the Square components created by the Board component: +Since the `Square` Component no longer accepts props anymore, you'll remove the `value` prop from all nine of the Square Components created by the Board component: ```js {6-8,11-13,16-18} // ... @@ -776,7 +776,7 @@ export default function Board() { } ``` -Now you'll change `Square` to display an "X" when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` component looks like this: +Now you'll change `Square` to display an "X" when clicked. Replace the `console.log("clicked!");` event handler with `setValue('X');`. Now your `Square` Component looks like this: ```js {5} function Square() { @@ -801,7 +801,7 @@ By calling this `set` function from an `onClick` handler, you're telling React t ![adding xes to board](../images/tutorial/tictac-adding-x-s.gif) -Each Square has its own state: the `value` stored in each Square is completely independent of the others. When you call a `set` function in a component, React automatically updates the child components inside too. +Each Square has its own state: the `value` stored in each Square is completely independent of the others. When you call a `set` function in a component, React automatically updates the child Components inside too. After you've made the above changes, your code will look like this: @@ -903,9 +903,9 @@ React DevTools let you check the props and the state of your React components. Y ![React DevTools in CodeSandbox](../images/tutorial/codesandbox-devtools.png) -To inspect a particular component on the screen, use the button in the top left corner of React DevTools: +To inspect a particular Component on the screen, use the button in the top left corner of React DevTools: -![Selecting components on the page with React DevTools](../images/tutorial/devtools-select.gif) +![Selecting Components on the page with React DevTools](../images/tutorial/devtools-select.gif) <Note> @@ -919,15 +919,15 @@ By this point, you have all the basic building blocks for your tic-tac-toe game. ### Lifting state up {/*lifting-state-up*/} -Currently, each `Square` component maintains a part of the game's state. To check for a winner in a tic-tac-toe game, the `Board` would need to somehow know the state of each of the 9 `Square` components. +Currently, each `Square` Component maintains a part of the game's state. To check for a winner in a tic-tac-toe game, the `Board` would need to somehow know the state of each of the 9 `Square` components. -How would you approach that? At first, you might guess that the `Board` needs to "ask" each `Square` for that `Square`'s state. Although this approach is technically possible in React, we discourage it because the code becomes difficult to understand, susceptible to bugs, and hard to refactor. Instead, the best approach is to store the game's state in the parent `Board` component instead of in each `Square`. The `Board` component can tell each `Square` what to display by passing a prop, like you did when you passed a number to each Square. +How would you approach that? At first, you might guess that the `Board` needs to "ask" each `Square` for that `Square`'s state. Although this approach is technically possible in React, we discourage it because the code becomes difficult to understand, susceptible to bugs, and hard to refactor. Instead, the best approach is to store the game's state in the parent `Board` Component instead of in each `Square`. The `Board` Component can tell each `Square` what to display by passing a prop, like you did when you passed a number to each Square. -**To collect data from multiple children, or to have two child components communicate with each other, declare the shared state in their parent component instead. The parent component can pass that state back down to the children via props. This keeps the child components in sync with each other and with their parent.** +**To collect data from multiple children, or to have two child Components communicate with each other, declare the shared state in their parent Component instead. The parent Component can pass that state back down to the children via props. This keeps the child Components in sync with each other and with their parent.** -Lifting state into a parent component is common when React components are refactored. +Lifting state into a parent Component is common when React Components are refactored. -Let's take this opportunity to try it out. Edit the `Board` component so that it declares a state variable named `squares` that defaults to an array of 9 nulls corresponding to the 9 squares: +Let's take this opportunity to try it out. Edit the `Board` Component so that it declares a state variable named `squares` that defaults to an array of 9 nulls corresponding to the 9 squares: ```js {3} // ... @@ -945,7 +945,7 @@ export default function Board() { ['O', null, 'X', 'X', 'X', 'O', 'O', null, null] ``` -Now your `Board` component needs to pass the `value` prop down to each `Square` that it renders: +Now your `Board` Component needs to pass the `value` prop down to each `Square` that it renders: ```js {6-8,11-13,16-18} export default function Board() { @@ -972,7 +972,7 @@ export default function Board() { } ``` -Next, you'll edit the `Square` component to receive the `value` prop from the Board component. This will require removing the Square component's own stateful tracking of `value` and the button's `onClick` prop: +Next, you'll edit the `Square` Component to receive the `value` prop from the Board component. This will require removing the Square component's own stateful tracking of `value` and the button's `onClick` prop: ```js {1,2} function Square({value}) { @@ -1068,9 +1068,9 @@ body { Each Square will now receive a `value` prop that will either be `'X'`, `'O'`, or `null` for empty squares. -Next, you need to change what happens when a `Square` is clicked. The `Board` component now maintains which squares are filled. You'll need to create a way for the `Square` to update the `Board`'s state. Since state is private to a component that defines it, you cannot update the `Board`'s state directly from `Square`. +Next, you need to change what happens when a `Square` is clicked. The `Board` Component now maintains which squares are filled. You'll need to create a way for the `Square` to update the `Board`'s state. Since state is private to a Component that defines it, you cannot update the `Board`'s state directly from `Square`. -Instead, you'll pass down a function from the `Board` component to the `Square` component, and you'll have `Square` call that function when a square is clicked. You'll start with the function that the `Square` component will call when it is clicked. You'll call that function `onSquareClick`: +Instead, you'll pass down a function from the `Board` Component to the `Square` component, and you'll have `Square` call that function when a square is clicked. You'll start with the function that the `Square` Component will call when it is clicked. You'll call that function `onSquareClick`: ```js {3} function Square({ value }) { @@ -1094,7 +1094,7 @@ function Square({ value, onSquareClick }) { } ``` -Now you'll connect the `onSquareClick` prop to a function in the `Board` component that you'll name `handleClick`. To connect `onSquareClick` to `handleClick` you'll pass a function to the `onSquareClick` prop of the first `Square` component: +Now you'll connect the `onSquareClick` prop to a function in the `Board` Component that you'll name `handleClick`. To connect `onSquareClick` to `handleClick` you'll pass a function to the `onSquareClick` prop of the first `Square` component: ```js {7} export default function Board() { @@ -1109,7 +1109,7 @@ export default function Board() { } ``` -Lastly, you will define the `handleClick` function inside the Board component to update the `squares` array holding your board's state: +Lastly, you will define the `handleClick` function inside the Board Component to update the `squares` array holding your board's state: ```js {4-8} export default function Board() { @@ -1129,7 +1129,7 @@ export default function Board() { The `handleClick` function creates a copy of the `squares` array (`nextSquares`) with the JavaScript `slice()` Array method. Then, `handleClick` updates the `nextSquares` array to add `X` to the first (`[0]` index) square. -Calling the `setSquares` function lets React know the state of the component has changed. This will trigger a re-render of the components that use the `squares` state (`Board`) as well as its child components (the `Square` components that make up the board). +Calling the `setSquares` function lets React know the state of the Component has changed. This will trigger a re-render of the Components that use the `squares` state (`Board`) as well as its child Components (the `Square` Components that make up the board). <Note> @@ -1161,7 +1161,7 @@ Next, you will need to pass that `i` to `handleClick`. You could try to set the <Square value={squares[0]} onSquareClick={handleClick(0)} /> ``` -Here is why this doesn't work. The `handleClick(0)` call will be a part of rendering the board component. Because `handleClick(0)` alters the state of the board component by calling `setSquares`, your entire board component will be re-rendered again. But this runs `handleClick(0)` again, leading to an infinite loop: +Here is why this doesn't work. The `handleClick(0)` call will be a part of rendering the board component. Because `handleClick(0)` alters the state of the board Component by calling `setSquares`, your entire board Component will be re-rendered again. But this runs `handleClick(0)` again, leading to an infinite loop: <ConsoleBlock level="error"> @@ -1317,19 +1317,19 @@ body { </Sandpack> -Now that your state handling is in the `Board` component, the parent `Board` component passes props to the child `Square` components so that they can be displayed correctly. When clicking on a `Square`, the child `Square` component now asks the parent `Board` component to update the state of the board. When the `Board`'s state changes, both the `Board` component and every child `Square` re-renders automatically. Keeping the state of all squares in the `Board` component will allow it to determine the winner in the future. +Now that your state handling is in the `Board` component, the parent `Board` Component passes props to the child `Square` Components so that they can be displayed correctly. When clicking on a `Square`, the child `Square` Component now asks the parent `Board` Component to update the state of the board. When the `Board`'s state changes, both the `Board` Component and every child `Square` re-renders automatically. Keeping the state of all squares in the `Board` Component will allow it to determine the winner in the future. Let's recap what happens when a user clicks the top left square on your board to add an `X` to it: -1. Clicking on the upper left square runs the function that the `button` received as its `onClick` prop from the `Square`. The `Square` component received that function as its `onSquareClick` prop from the `Board`. The `Board` component defined that function directly in the JSX. It calls `handleClick` with an argument of `0`. +1. Clicking on the upper left square runs the function that the `button` received as its `onClick` prop from the `Square`. The `Square` Component received that function as its `onSquareClick` prop from the `Board`. The `Board` Component defined that function directly in the JSX. It calls `handleClick` with an argument of `0`. 1. `handleClick` uses the argument (`0`) to update the first element of the `squares` array from `null` to `X`. -1. The `squares` state of the `Board` component was updated, so the `Board` and all of its children re-render. This causes the `value` prop of the `Square` component with index `0` to change from `null` to `X`. +1. The `squares` state of the `Board` Component was updated, so the `Board` and all of its children re-render. This causes the `value` prop of the `Square` Component with index `0` to change from `null` to `X`. In the end the user sees that the upper left square has changed from empty to having a `X` after clicking it. <Note> -The DOM `<button>` element's `onClick` attribute has a special meaning to React because it is a built-in component. For custom components like Square, the naming is up to you. You could give any name to the `Square`'s `onSquareClick` prop or `Board`'s `handleClick` function, and the code would work the same. In React, it's conventional to use `onSomething` names for props which represent events and `handleSomething` for the function definitions which handle those events. +The DOM `<button>` element's `onClick` attribute has a special meaning to React because it is a built-in component. For custom Components like Square, the naming is up to you. You could give any name to the `Square`'s `onSquareClick` prop or `Board`'s `handleClick` function, and the code would work the same. In React, it's conventional to use `onSomething` names for props which represent events and `handleSomething` for the function definitions which handle those events. </Note> @@ -1357,7 +1357,7 @@ The result is the same but by not mutating (changing the underlying data) direct Immutability makes complex features much easier to implement. Later in this tutorial, you will implement a "time travel" feature that lets you review the game's history and "jump back" to past moves. This functionality isn't specific to games--an ability to undo and redo certain actions is a common requirement for apps. Avoiding direct data mutation lets you keep previous versions of the data intact, and reuse them later. -There is also another benefit of immutability. By default, all child components re-render automatically when the state of a parent component changes. This includes even the child components that weren't affected by the change. Although re-rendering is not by itself noticeable to the user (you shouldn't actively try to avoid it!), you might want to skip re-rendering a part of the tree that clearly wasn't affected by it for performance reasons. Immutability makes it very cheap for components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a component in [the `memo` API reference](/reference/react/memo). +There is also another benefit of immutability. By default, all child Components re-render automatically when the state of a parent Component changes. This includes even the child Components that weren't affected by the change. Although re-rendering is not by itself noticeable to the user (you shouldn't actively try to avoid it!), you might want to skip re-rendering a part of the tree that clearly wasn't affected by it for performance reasons. Immutability makes it very cheap for Components to compare whether their data has changed or not. You can learn more about how React chooses when to re-render a Component in [the `memo` API reference](/reference/react/memo). ### Taking turns {/*taking-turns*/} @@ -1747,11 +1747,11 @@ You'll store the past `squares` arrays in another array called `history`, which ### Lifting state up, again {/*lifting-state-up-again*/} -You will now write a new top-level component called `Game` to display a list of past moves. That's where you will place the `history` state that contains the entire game history. +You will now write a new top-level Component called `Game` to display a list of past moves. That's where you will place the `history` state that contains the entire game history. -Placing the `history` state into the `Game` component will let you remove the `squares` state from its child `Board` component. Just like you "lifted state up" from the `Square` component into the `Board` component, you will now lift it up from the `Board` into the top-level `Game` component. This gives the `Game` component full control over the `Board`'s data and lets it instruct the `Board` to render previous turns from the `history`. +Placing the `history` state into the `Game` Component will let you remove the `squares` state from its child `Board` component. Just like you "lifted state up" from the `Square` Component into the `Board` component, you will now lift it up from the `Board` into the top-level `Game` component. This gives the `Game` Component full control over the `Board`'s data and lets it instruct the `Board` to render previous turns from the `history`. -First, add a `Game` component with `export default`. Have it render the `Board` component and some markup: +First, add a `Game` Component with `export default`. Have it render the `Board` Component and some markup: ```js {1,5-16} function Board() { @@ -1772,9 +1772,9 @@ export default function Game() { } ``` -Note that you are removing the `export default` keywords before the `function Board() {` declaration and adding them before the `function Game() {` declaration. This tells your `index.js` file to use the `Game` component as the top-level component instead of your `Board` component. The additional `div`s returned by the `Game` component are making room for the game information you'll add to the board later. +Note that you are removing the `export default` keywords before the `function Board() {` declaration and adding them before the `function Game() {` declaration. This tells your `index.js` file to use the `Game` Component as the top-level Component instead of your `Board` component. The additional `div`s returned by the `Game` Component are making room for the game information you'll add to the board later. -Add some state to the `Game` component to track which player is next and the history of moves: +Add some state to the `Game` Component to track which player is next and the history of moves: ```js {2-3} export default function Game() { @@ -1795,7 +1795,7 @@ export default function Game() { // ... ``` -Next, create a `handlePlay` function inside the `Game` component that will be called by the `Board` component to update the game. Pass `xIsNext`, `currentSquares` and `handlePlay` as props to the `Board` component: +Next, create a `handlePlay` function inside the `Game` Component that will be called by the `Board` Component to update the game. Pass `xIsNext`, `currentSquares` and `handlePlay` as props to the `Board` component: ```js {6-8,13} export default function Game() { @@ -1816,7 +1816,7 @@ export default function Game() { } ``` -Let's make the `Board` component fully controlled by the props it receives. Change the `Board` component to take three props: `xIsNext`, `squares`, and a new `onPlay` function that `Board` can call with the updated squares array when a player makes a move. Next, remove the first two lines of the `Board` function that call `useState`: +Let's make the `Board` Component fully controlled by the props it receives. Change the `Board` Component to take three props: `xIsNext`, `squares`, and a new `onPlay` function that `Board` can call with the updated squares array when a player makes a move. Next, remove the first two lines of the `Board` function that call `useState`: ```js {1} function Board({ xIsNext, squares, onPlay }) { @@ -1827,7 +1827,7 @@ function Board({ xIsNext, squares, onPlay }) { } ``` -Now replace the `setSquares` and `setXIsNext` calls in `handleClick` in the `Board` component with a single call to your new `onPlay` function so the `Game` component can update the `Board` when the user clicks a square: +Now replace the `setSquares` and `setXIsNext` calls in `handleClick` in the `Board` Component with a single call to your new `onPlay` function so the `Game` Component can update the `Board` when the user clicks a square: ```js {12} function Board({ xIsNext, squares, onPlay }) { @@ -1847,7 +1847,7 @@ function Board({ xIsNext, squares, onPlay }) { } ``` -The `Board` component is fully controlled by the props passed to it by the `Game` component. You need to implement the `handlePlay` function in the `Game` component to get the game working again. +The `Board` Component is fully controlled by the props passed to it by the `Game` component. You need to implement the `handlePlay` function in the `Game` Component to get the game working again. What should `handlePlay` do when called? Remember that Board used to call `setSquares` with an updated array; now it passes the updated `squares` array to `onPlay`. @@ -2280,17 +2280,17 @@ In addition to the updated counts, a human reading this would probably say that </li> ``` -When a list is re-rendered, React takes each list item's key and searches the previous list's items for a matching key. If the current list has a key that didn't exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding component is moved. +When a list is re-rendered, React takes each list item's key and searches the previous list's items for a matching key. If the current list has a key that didn't exist before, React creates a component. If the current list is missing a key that existed in the previous list, React destroys the previous component. If two keys match, the corresponding Component is moved. -Keys tell React about the identity of each component, which allows React to maintain state between re-renders. If a component's key changes, the component will be destroyed and re-created with a new state. +Keys tell React about the identity of each component, which allows React to maintain state between re-renders. If a component's key changes, the Component will be destroyed and re-created with a new state. -`key` is a special and reserved property in React. When an element is created, React extracts the `key` property and stores the key directly on the returned element. Even though `key` may look like it is passed as props, React automatically uses `key` to decide which components to update. There's no way for a component to ask what `key` its parent specified. +`key` is a special and reserved property in React. When an element is created, React extracts the `key` property and stores the key directly on the returned element. Even though `key` may look like it is passed as props, React automatically uses `key` to decide which Components to update. There's no way for a Component to ask what `key` its parent specified. **It's strongly recommended that you assign proper keys whenever you build dynamic lists.** If you don't have an appropriate key, you may want to consider restructuring your data so that you do. If no key is specified, React will report an error and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list's items or inserting/removing list items. Explicitly passing `key={i}` silences the error but has the same problems as array indices and is not recommended in most cases. -Keys do not need to be globally unique; they only need to be unique between components and their siblings. +Keys do not need to be globally unique; they only need to be unique between Components and their siblings. ### Implementing time travel {/*implementing-time-travel*/} @@ -2476,7 +2476,7 @@ body { </Sandpack> -Before you can implement `jumpTo`, you need the `Game` component to keep track of which step the user is currently viewing. To do this, define a new state variable called `currentMove`, defaulting to `0`: +Before you can implement `jumpTo`, you need the `Game` Component to keep track of which step the user is currently viewing. To do this, define a new state variable called `currentMove`, defaulting to `0`: ```js {4} export default function Game() { @@ -2515,7 +2515,7 @@ function handlePlay(nextSquares) { } ``` -Finally, you will modify the `Game` component to render the currently selected move, instead of always rendering the final move: +Finally, you will modify the `Game` Component to render the currently selected move, instead of always rendering the final move: ```js {5} export default function Game() { diff --git a/src/content/learn/typescript.md b/src/content/learn/typescript.md index 6f49c76567c..980e00714c7 100644 --- a/src/content/learn/typescript.md +++ b/src/content/learn/typescript.md @@ -49,7 +49,7 @@ Every file containing JSX must use the `.tsx` file extension. This is a TypeScri </Note> -Writing TypeScript with React is very similar to writing JavaScript with React. The key difference when working with a component is that you can provide types for your component's props. These types can be used for correctness checking and providing inline documentation in editors. +Writing TypeScript with React is very similar to writing JavaScript with React. The key difference when working with a Component is that you can provide types for your component's props. These types can be used for correctness checking and providing inline documentation in editors. Taking the [`MyButton` component](/learn#components) from the [Quick Start](/learn) guide, we can add a type describing the `title` for the button: @@ -124,7 +124,7 @@ The type describing your component's props can be as simple or as complex as you ## Example Hooks {/*example-hooks*/} -The type definitions from `@types/react` include types for the built-in Hooks, so you can use them in your components without any additional setup. They are built to take into account the code you write in your component, so you will get [inferred types](https://www.typescriptlang.org/docs/handbook/type-inference.html) a lot of the time and ideally do not need to handle the minutiae of providing the types. +The type definitions from `@types/react` include types for the built-in Hooks, so you can use them in your Components without any additional setup. They are built to take into account the code you write in your component, so you will get [inferred types](https://www.typescriptlang.org/docs/handbook/type-inference.html) a lot of the time and ideally do not need to handle the minutiae of providing the types. However, we can look at a few examples of how to provide types for Hooks. @@ -242,7 +242,7 @@ export default function App() { ### `useContext` {/*typing-usecontext*/} -The [`useContext` Hook](/reference/react/useContext) is a technique for passing data down the component tree without having to pass props through components. It is used by creating a provider component and often by creating a Hook to consume the value in a child component. +The [`useContext` Hook](/reference/react/useContext) is a technique for passing data down the Component tree without having to pass props through components. It is used by creating a provider Component and often by creating a Hook to consume the value in a child component. The type of the value provided by the context is inferred from the value passed to the `createContext` call: @@ -433,7 +433,7 @@ interface ModalRendererProps { } ``` -Note, that you cannot use TypeScript to describe that the children are a certain type of JSX elements, so you cannot use the type-system to describe a component which only accepts `<li>` children. +Note, that you cannot use TypeScript to describe that the children are a certain type of JSX elements, so you cannot use the type-system to describe a Component which only accepts `<li>` children. You can see an example of both `React.ReactNode` and `React.ReactElement` with the type-checker in [this TypeScript playground](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wChSB6CxYmAOmXRgDkIATJOdNJMGAZzgwAFpxAR+8YADswAVwGkZMJFEzpOjDKw4AFHGEEBvUnDhphwADZsi0gFw0mDWjqQBuUgF9yaCNMlENzgAXjgACjADfkctFnYkfQhDAEpQgD44AB42YAA3dKMo5P46C2tbJGkvLIpcgt9-QLi3AEEwMFCItJDMrPTTbIQ3dKywdIB5aU4kKyQQKpha8drhhIGzLLWODbNs3b3s8YAxKBQAcwXpAThMaGWDvbH0gFloGbmrgQfBzYpd1YjQZbEYARkB6zMwO2SHSAAlZlYIBCdtCRkZpHIrFYahQYQD8UYYFA5EhcfjyGYqHAXnJAsIUHlOOUbHYhMIIHJzsI0Qk4P9SLUBuRqXEXEwAKKfRZcNA8PiCfxWACecAAUgBlAAacFm80W-CU11U6h4TgwUv11yShjgJjMLMqDnN9Dilq+nh8pD8AXgCHdMrCkWisVoAet0R6fXqhWKhjKllZVVxMcavpd4Zg7U6Qaj+2hmdG4zeRF10uu-Aeq0LBfLMEe-V+T2L7zLVu+FBWLdLeq+lc7DYFf39deFVOotMCACNOCh1dq219a+30uC8YWoZsRyuEdjkevR8uvoVMdjyTWt4WiSSydXD4NqZP4AymeZE072ZzuUeZQKheQgA). 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 2abf7affc71..f2231c49070 100644 --- a/src/content/learn/understanding-your-ui-as-a-tree.md +++ b/src/content/learn/understanding-your-ui-as-a-tree.md @@ -4,7 +4,7 @@ title: Understanding Your UI as a Tree <Intro> -Your React app is taking shape with many components being nested within each other. How does React keep track of your app's component structure? +Your React app is taking shape with many Components being nested within each other. How does React keep track of your app's Component structure? React, and many other UI libraries, model UI as a tree. Thinking of your app as a tree is useful for understanding the relationship between components. This understanding will help you debug future concepts like performance and state management. @@ -12,7 +12,7 @@ React, and many other UI libraries, model UI as a tree. Thinking of your app as <YouWillLearn> -* How React "sees" component structures +* How React "sees" Component structures * What a render tree is and what it is useful for * What a module dependency tree is and what it is useful for @@ -27,11 +27,11 @@ Trees are a relationship model between items and UI is often represented using t React creates a UI tree from your components. In this example, the UI tree is then used to render to the DOM. </Diagram> -Like browsers and mobile platforms, React also uses tree structures to manage and model the relationship between components in a React app. These trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size. +Like browsers and mobile platforms, React also uses tree structures to manage and model the relationship between Components in a React app. These trees are useful tools to understand how data flows through a React app and how to optimize rendering and app size. ## The Render Tree {/*the-render-tree*/} -A major feature of components is the ability to compose components of other components. As we [nest components](/learn/your-first-component#nesting-and-organizing-components), we have the concept of parent and child components, where each parent component may itself be a child of another component. +A major feature of Components is the ability to compose Components of other components. As we [nest components](/learn/your-first-component#nesting-and-organizing-components), we have the concept of parent and child components, where each parent Component may itself be a child of another component. When we render a React app, we can model this relationship in a tree, known as the render tree. @@ -129,13 +129,13 @@ From the example app, we can construct the above render tree. The tree is composed of nodes, each of which represents a component. `App`, `FancyText`, `Copyright`, to name a few, are all nodes in our tree. -The root node in a React render tree is the [root component](/learn/importing-and-exporting-components#the-root-component-file) of the app. In this case, the root component is `App` and it is the first component React renders. Each arrow in the tree points from a parent component to a child component. +The root node in a React render tree is the [root component](/learn/importing-and-exporting-components#the-root-component-file) of the app. In this case, the root Component is `App` and it is the first Component React renders. Each arrow in the tree points from a parent Component to a child component. <DeepDive> #### Where are the HTML tags in the render tree? {/*where-are-the-html-elements-in-the-render-tree*/} -You'll notice in the above render tree, there is no mention of the HTML tags that each component renders. This is because the render tree is only composed of React [components](learn/your-first-component#components-ui-building-blocks). +You'll notice in the above render tree, there is no mention of the HTML tags that each Component renders. This is because the render tree is only composed of React [components](learn/your-first-component#components-ui-building-blocks). React, as a UI framework, is platform agnostic. On react.dev, we showcase examples that render to the web, which uses HTML markup as its UI primitives. But a React app could just as likely render to a mobile or desktop platform, which may use different UI primitives like [UIView](https://developer.apple.com/documentation/uikit/uiview) or [FrameworkElement](https://learn.microsoft.com/en-us/dotnet/api/system.windows.frameworkelement?view=windowsdesktop-7.0). @@ -143,7 +143,7 @@ These platform UI primitives are not a part of React. React render trees can pro </DeepDive> -A render tree represents a single render pass of a React application. With [conditional rendering](/learn/conditional-rendering), a parent component may render different children depending on the data passed. +A render tree represents a single render pass of a React application. With [conditional rendering](/learn/conditional-rendering), a parent Component may render different children depending on the data passed. We can update the app to conditionally render either an inspirational quote or color. @@ -253,9 +253,9 @@ With conditional rendering, across different renders, the render tree may render In this example, depending on what `inspiration.type` is, we may render `<FancyText>` or `<Color>`. The render tree may be different for each render pass. -Although render trees may differ across render passes, these trees are generally helpful for identifying what the *top-level* and *leaf components* are in a React app. Top-level components are the components nearest to the root component and affect the rendering performance of all the components beneath them and often contain the most complexity. Leaf components are near the bottom of the tree and have no child components and are often frequently re-rendered. +Although render trees may differ across render passes, these trees are generally helpful for identifying what the *top-level* and *leaf components* are in a React app. Top-level Components are the Components nearest to the root Component and affect the rendering performance of all the Components beneath them and often contain the most complexity. Leaf Components are near the bottom of the tree and have no child Components and are often frequently re-rendered. -Identifying these categories of components are useful for understanding data flow and performance of your app. +Identifying these categories of Components are useful for understanding data flow and performance of your app. ## The Module Dependency Tree {/*the-module-dependency-tree*/} @@ -277,7 +277,7 @@ Comparing to the render tree of the same app, there are similar structures but s * The nodes that make-up the tree represent modules, not components. * Non-component modules, like `inspirations.js`, are also represented in this tree. The render tree only encapsulates components. -* `Copyright.js` appears under `App.js` but in the render tree, `Copyright`, the component, appears as a child of `InspirationGenerator`. This is because `InspirationGenerator` accepts JSX as [children props](/learn/passing-props-to-a-component#passing-jsx-as-children), so it renders `Copyright` as a child component but does not import the module. +* `Copyright.js` appears under `App.js` but in the render tree, `Copyright`, the component, appears as a child of `InspirationGenerator`. This is because `InspirationGenerator` accepts JSX as [children props](/learn/passing-props-to-a-component#passing-jsx-as-children), so it renders `Copyright` as a child Component but does not import the module. Dependency trees are useful to determine what modules are necessary to run your React app. When building a React app for production, there is typically a build step that will bundle all the necessary JavaScript to ship to the client. The tool responsible for this is called a [bundler](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Understanding_client-side_tools/Overview#the_modern_tooling_ecosystem), and bundlers will use the dependency tree to determine what modules should be included. @@ -288,9 +288,9 @@ As your app grows, often the bundle size does too. Large bundle sizes are expens <Recap> * Trees are a common way to represent the relationship between entities. They are often used to model UI. -* Render trees represent the nested relationship between React components across a single render. -* With conditional rendering, the render tree may change across different renders. With different prop values, components may render different children components. -* Render trees help identify what the top-level and leaf components are. Top-level components affect the rendering performance of all components beneath them and leaf components are often re-rendered frequently. Identifying them is useful for understanding and debugging rendering performance. +* Render trees represent the nested relationship between React Components across a single render. +* With conditional rendering, the render tree may change across different renders. With different prop values, Components may render different children components. +* Render trees help identify what the top-level and leaf Components are. Top-level Components affect the rendering performance of all Components beneath them and leaf Components are often re-rendered frequently. Identifying them is useful for understanding and debugging rendering performance. * Dependency trees represent the module dependencies in a React app. * Dependency trees are used by build tools to bundle the necessary code to ship an app. * Dependency trees are useful for debugging large bundle sizes that slow time to paint and expose opportunities for optimizing what code is bundled. diff --git a/src/content/learn/updating-objects-in-state.md b/src/content/learn/updating-objects-in-state.md index 923e4e181f9..f09a8657486 100644 --- a/src/content/learn/updating-objects-in-state.md +++ b/src/content/learn/updating-objects-in-state.md @@ -119,7 +119,7 @@ onPointerMove={e => { With `setPosition`, you're telling React: * Replace `position` with this new object -* And render this component again +* And render this Component again Notice how the red dot now follows your pointer when you touch or hover over the preview area: @@ -788,7 +788,7 @@ img { width: 200px; height: 200px; } </Sandpack> -Notice how much more concise the event handlers have become. You can mix and match `useState` and `useImmer` in a single component as much as you like. Immer is a great way to keep the update handlers concise, especially if there's nesting in your state, and copying objects leads to repetitive code. +Notice how much more concise the event handlers have become. You can mix and match `useState` and `useImmer` in a single Component as much as you like. Immer is a great way to keep the update handlers concise, especially if there's nesting in your state, and copying objects leads to repetitive code. <DeepDive> diff --git a/src/content/learn/writing-markup-with-jsx.md b/src/content/learn/writing-markup-with-jsx.md index 62670150aca..92983ae1fdd 100644 --- a/src/content/learn/writing-markup-with-jsx.md +++ b/src/content/learn/writing-markup-with-jsx.md @@ -40,13 +40,13 @@ But as the Web became more interactive, logic increasingly determined content. J <DiagramGroup> -<Diagram name="writing_jsx_sidebar" height={330} width={325} alt="React component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the component shown in the next diagram."> +<Diagram name="writing_jsx_sidebar" height={330} width={325} alt="React Component with HTML and JavaScript from previous examples mixed. Function name is Sidebar which calls the function isLoggedIn, highlighted in yellow. Nested inside the function highlighted in purple is the p tag from before, and a Form tag referencing the Component shown in the next diagram."> `Sidebar.js` React component </Diagram> -<Diagram name="writing_jsx_form" height={330} width={325} alt="React component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop."> +<Diagram name="writing_jsx_form" height={330} width={325} alt="React Component with HTML and JavaScript from previous examples mixed. Function name is Form containing two handlers onClick and onSubmit highlighted in yellow. Following the handlers is HTML highlighted in purple. The HTML contains a form element with a nested input element, each with an onClick prop."> `Form.js` React component @@ -56,7 +56,7 @@ But as the Web became more interactive, logic increasingly determined content. J Keeping a button's rendering logic and markup together ensures that they stay in sync with each other on every edit. Conversely, details that are unrelated, such as the button's markup and a sidebar's markup, are isolated from each other, making it safer to change either of them on their own. -Each React component is a JavaScript function that may contain some markup that React renders into the browser. React components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information. The best way to understand this is to convert some HTML markup to JSX markup. +Each React Component is a JavaScript function that may contain some markup that React renders into the browser. React Components use a syntax extension called JSX to represent that markup. JSX looks a lot like HTML, but it is a bit stricter and can display dynamic information. The best way to understand this is to convert some HTML markup to JSX markup. <Note> @@ -214,7 +214,7 @@ This is why, in React, many HTML and SVG attributes are written in camelCase. Fo /> ``` -You can [find all these attributes in the list of DOM component props.](/reference/react-dom/components/common) If you get one wrong, don't worry—React will print a message with a possible correction to the [browser console.](https://developer.mozilla.org/docs/Tools/Browser_Console) +You can [find all these attributes in the list of DOM Component props.](/reference/react-dom/components/common) If you get one wrong, don't worry—React will print a message with a possible correction to the [browser console.](https://developer.mozilla.org/docs/Tools/Browser_Console) <Pitfall> @@ -260,7 +260,7 @@ img { height: 90px } Now you know why JSX exists and how to use it in components: -* React components group rendering logic together with markup because they are related. +* React Components group rendering logic together with markup because they are related. * JSX is similar to HTML, with a few differences. You can use a [converter](https://transform.tools/html-to-jsx) if you need to. * Error messages will often point you in the right direction to fixing your markup. 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 66cdc311775..fca96da09d4 100644 --- a/src/content/learn/you-might-not-need-an-effect.md +++ b/src/content/learn/you-might-not-need-an-effect.md @@ -4,7 +4,7 @@ title: 'You Might Not Need an Effect' <Intro> -Effects are an escape hatch from the React paradigm. They let you "step outside" of React and synchronize your components with some external system like a non-React widget, network, or the browser DOM. If there is no external system involved (for example, if you want to update a component's state when some props or state change), you shouldn't need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone. +Effects are an escape hatch from the React paradigm. They let you "step outside" of React and synchronize your Components with some external system like a non-React widget, network, or the browser DOM. If there is no external system involved (for example, if you want to update a component's state when some props or state change), you shouldn't need an Effect. Removing unnecessary Effects will make your code easier to follow, faster to run, and less error-prone. </Intro> @@ -12,10 +12,10 @@ Effects are an escape hatch from the React paradigm. They let you "step outside" * Why and how to remove unnecessary Effects from your components * How to cache expensive computations without Effects -* How to reset and adjust component state without Effects +* How to reset and adjust Component state without Effects * How to share logic between event handlers * Which logic should be moved to event handlers -* How to notify parent components about changes +* How to notify parent Components about changes </YouWillLearn> @@ -23,7 +23,7 @@ Effects are an escape hatch from the React paradigm. They let you "step outside" There are two common cases in which you don't need Effects: -* **You don't need Effects to transform data for rendering.** For example, let's say you want to filter a list before displaying it. You might feel tempted to write an Effect that updates a state variable when the list changes. However, this is inefficient. When you update the state, React will first call your component functions to calculate what should be on the screen. Then React will ["commit"](/learn/render-and-commit) these changes to the DOM, updating the screen. Then React will run your Effects. If your Effect *also* immediately updates the state, this restarts the whole process from scratch! To avoid the unnecessary render passes, transform all the data at the top level of your components. That code will automatically re-run whenever your props or state change. +* **You don't need Effects to transform data for rendering.** For example, let's say you want to filter a list before displaying it. You might feel tempted to write an Effect that updates a state variable when the list changes. However, this is inefficient. When you update the state, React will first call your Component functions to calculate what should be on the screen. Then React will ["commit"](/learn/render-and-commit) these changes to the DOM, updating the screen. Then React will run your Effects. If your Effect *also* immediately updates the state, this restarts the whole process from scratch! To avoid the unnecessary render passes, transform all the data at the top level of your components. That code will automatically re-run whenever your props or state change. * **You don't need Effects to handle user events.** For example, let's say you want to send an `/api/buy` POST request and show a notification when the user buys a product. In the Buy button click event handler, you know exactly what happened. By the time an Effect runs, you don't know *what* the user did (for example, which button was clicked). This is why you'll usually handle user events in the corresponding event handlers. You *do* need Effects to [synchronize](/learn/synchronizing-with-effects#what-are-effects-and-how-are-they-different-from-events) with external systems. For example, you can write an Effect that keeps a jQuery widget synchronized with the React state. You can also fetch data with Effects: for example, you can synchronize the search results with the current search query. Keep in mind that modern [frameworks](/learn/start-a-new-react-project#production-grade-react-frameworks) provide more efficient built-in data fetching mechanisms than writing Effects directly in your components. @@ -32,7 +32,7 @@ To help you gain the right intuition, let's look at some common concrete example ### Updating state based on props or state {/*updating-state-based-on-props-or-state*/} -Suppose you have a component with two state variables: `firstName` and `lastName`. You want to calculate a `fullName` from them by concatenating them. Moreover, you'd like `fullName` to update whenever `firstName` or `lastName` change. Your first instinct might be to add a `fullName` state variable and update it in an Effect: +Suppose you have a Component with two state variables: `firstName` and `lastName`. You want to calculate a `fullName` from them by concatenating them. Moreover, you'd like `fullName` to update whenever `firstName` or `lastName` change. Your first instinct might be to add a `fullName` state variable and update it in an Effect: ```js {5-9} function Form() { @@ -64,7 +64,7 @@ function Form() { ### Caching expensive calculations {/*caching-expensive-calculations*/} -This component computes `visibleTodos` by taking the `todos` it receives by props and filtering them according to the `filter` prop. You might feel tempted to store the result in state and update it from an Effect: +This Component computes `visibleTodos` by taking the `todos` it receives by props and filtering them according to the `filter` prop. You might feel tempted to store the result in state and update it from an Effect: ```js {4-8} function TodoList({ todos, filter }) { @@ -151,13 +151,13 @@ console.timeEnd('filter array'); Keep in mind that your machine is probably faster than your users' so it's a good idea to test the performance with an artificial slowdown. For example, Chrome offers a [CPU Throttling](https://developer.chrome.com/blog/new-in-devtools-61/#throttling) option for this. -Also note that measuring performance in development will not give you the most accurate results. (For example, when [Strict Mode](/reference/react/StrictMode) is on, you will see each component render twice rather than once.) To get the most accurate timings, build your app for production and test it on a device like your users have. +Also note that measuring performance in development will not give you the most accurate results. (For example, when [Strict Mode](/reference/react/StrictMode) is on, you will see each Component render twice rather than once.) To get the most accurate timings, build your app for production and test it on a device like your users have. </DeepDive> ### Resetting all state when a prop changes {/*resetting-all-state-when-a-prop-changes*/} -This `ProfilePage` component receives a `userId` prop. The page contains a comment input, and you use a `comment` state variable to hold its value. One day, you notice a problem: when you navigate from one profile to another, the `comment` state does not get reset. As a result, it's easy to accidentally post a comment on a wrong user's profile. To fix the issue, you want to clear out the `comment` state variable whenever the `userId` changes: +This `ProfilePage` Component receives a `userId` prop. The page contains a comment input, and you use a `comment` state variable to hold its value. One day, you notice a problem: when you navigate from one profile to another, the `comment` state does not get reset. As a result, it's easy to accidentally post a comment on a wrong user's profile. To fix the issue, you want to clear out the `comment` state variable whenever the `userId` changes: ```js {4-7} export default function ProfilePage({ userId }) { @@ -171,9 +171,9 @@ export default function ProfilePage({ userId }) { } ``` -This is inefficient because `ProfilePage` and its children will first render with the stale value, and then render again. It is also complicated because you'd need to do this in *every* component that has some state inside `ProfilePage`. For example, if the comment UI is nested, you'd want to clear out nested comment state too. +This is inefficient because `ProfilePage` and its children will first render with the stale value, and then render again. It is also complicated because you'd need to do this in *every* Component that has some state inside `ProfilePage`. For example, if the comment UI is nested, you'd want to clear out nested comment state too. -Instead, you can tell React that each user's profile is conceptually a _different_ profile by giving it an explicit key. Split your component in two and pass a `key` attribute from the outer component to the inner one: +Instead, you can tell React that each user's profile is conceptually a _different_ profile by giving it an explicit key. Split your Component in two and pass a `key` attribute from the outer Component to the inner one: ```js {5,11-12} export default function ProfilePage({ userId }) { @@ -192,15 +192,15 @@ function Profile({ userId }) { } ``` -Normally, React preserves the state when the same component is rendered in the same spot. **By passing `userId` as a `key` to the `Profile` component, you're asking React to treat two `Profile` components with different `userId` as two different components that should not share any state.** Whenever the key (which you've set to `userId`) changes, React will recreate the DOM and [reset the state](/learn/preserving-and-resetting-state#option-2-resetting-state-with-a-key) of the `Profile` component and all of its children. Now the `comment` field will clear out automatically when navigating between profiles. +Normally, React preserves the state when the same Component is rendered in the same spot. **By passing `userId` as a `key` to the `Profile` component, you're asking React to treat two `Profile` Components with different `userId` as two different Components that should not share any state.** Whenever the key (which you've set to `userId`) changes, React will recreate the DOM and [reset the state](/learn/preserving-and-resetting-state#option-2-resetting-state-with-a-key) of the `Profile` Component and all of its children. Now the `comment` field will clear out automatically when navigating between profiles. -Note that in this example, only the outer `ProfilePage` component is exported and visible to other files in the project. Components rendering `ProfilePage` don't need to pass the key to it: they pass `userId` as a regular prop. The fact `ProfilePage` passes it as a `key` to the inner `Profile` component is an implementation detail. +Note that in this example, only the outer `ProfilePage` Component is exported and visible to other files in the project. Components rendering `ProfilePage` don't need to pass the key to it: they pass `userId` as a regular prop. The fact `ProfilePage` passes it as a `key` to the inner `Profile` Component is an implementation detail. ### Adjusting some state when a prop changes {/*adjusting-some-state-when-a-prop-changes*/} Sometimes, you might want to reset or adjust a part of the state on a prop change, but not all of it. -This `List` component receives a list of `items` as a prop, and maintains the selected item in the `selection` state variable. You want to reset the `selection` to `null` whenever the `items` prop receives a different array: +This `List` Component receives a list of `items` as a prop, and maintains the selected item in the `selection` state variable. You want to reset the `selection` to `null` whenever the `items` prop receives a different array: ```js {5-8} function List({ items }) { @@ -215,7 +215,7 @@ function List({ items }) { } ``` -This, too, is not ideal. Every time the `items` change, the `List` and its child components will render with a stale `selection` value at first. Then React will update the DOM and run the Effects. Finally, the `setSelection(null)` call will cause another re-render of the `List` and its child components, restarting this whole process again. +This, too, is not ideal. Every time the `items` change, the `List` and its child Components will render with a stale `selection` value at first. Then React will update the DOM and run the Effects. Finally, the `setSelection(null)` call will cause another re-render of the `List` and its child components, restarting this whole process again. Start by deleting the Effect. Instead, adjust the state directly during rendering: @@ -236,9 +236,9 @@ function List({ items }) { [Storing information from previous renders](/reference/react/useState#storing-information-from-previous-renders) like this can be hard to understand, but it’s better than updating the same state in an Effect. In the above example, `setSelection` is called directly during a render. React will re-render the `List` *immediately* after it exits with a `return` statement. React has not rendered the `List` children or updated the DOM yet, so this lets the `List` children skip rendering the stale `selection` value. -When you update a component during rendering, React throws away the returned JSX and immediately retries rendering. To avoid very slow cascading retries, React only lets you update the *same* component's state during a render. If you update another component's state during a render, you'll see an error. A condition like `items !== prevItems` is necessary to avoid loops. You may adjust state like this, but any other side effects (like changing the DOM or setting timeouts) should stay in event handlers or Effects to [keep components pure.](/learn/keeping-components-pure) +When you update a Component during rendering, React throws away the returned JSX and immediately retries rendering. To avoid very slow cascading retries, React only lets you update the *same* component's state during a render. If you update another component's state during a render, you'll see an error. A condition like `items !== prevItems` is necessary to avoid loops. You may adjust state like this, but any other side effects (like changing the DOM or setting timeouts) should stay in event handlers or Effects to [keep Components pure.](/learn/keeping-components-pure) -**Although this pattern is more efficient than an Effect, most components shouldn't need it either.** No matter how you do it, adjusting state based on props or other state makes your data flow more difficult to understand and debug. Always check whether you can [reset all state with a key](#resetting-all-state-when-a-prop-changes) or [calculate everything during rendering](#updating-state-based-on-props-or-state) instead. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:* +**Although this pattern is more efficient than an Effect, most Components shouldn't need it either.** No matter how you do it, adjusting state based on props or other state makes your data flow more difficult to understand and debug. Always check whether you can [reset all state with a key](#resetting-all-state-when-a-prop-changes) or [calculate everything during rendering](#updating-state-based-on-props-or-state) instead. For example, instead of storing (and resetting) the selected *item*, you can store the selected *item ID:* ```js {3-5} function List({ items }) { @@ -279,7 +279,7 @@ function ProductPage({ product, addToCart }) { This Effect is unnecessary. It will also most likely cause bugs. For example, let's say that your app "remembers" the shopping cart between the page reloads. If you add a product to the cart once and refresh the page, the notification will appear again. It will keep appearing every time you refresh that product's page. This is because `product.isInCart` will already be `true` on the page load, so the Effect above will call `showNotification()`. -**When you're not sure whether some code should be in an Effect or in an event handler, ask yourself *why* this code needs to run. Use Effects only for code that should run *because* the component was displayed to the user.** In this example, the notification should appear because the user *pressed the button*, not because the page was displayed! Delete the Effect and put the shared logic into a function called from both event handlers: +**When you're not sure whether some code should be in an Effect or in an event handler, ask yourself *why* this code needs to run. Use Effects only for code that should run *because* the Component was displayed to the user.** In this example, the notification should appear because the user *pressed the button*, not because the page was displayed! Delete the Effect and put the shared logic into a function called from both event handlers: ```js {2-6,9,13} function ProductPage({ product, addToCart }) { @@ -305,14 +305,14 @@ This both removes the unnecessary Effect and fixes the bug. ### Sending a POST request {/*sending-a-post-request*/} -This `Form` component sends two kinds of POST requests. It sends an analytics event when it mounts. When you fill in the form and click the Submit button, it will send a POST request to the `/api/register` endpoint: +This `Form` Component sends two kinds of POST requests. It sends an analytics event when it mounts. When you fill in the form and click the Submit button, it will send a POST request to the `/api/register` endpoint: ```js {5-8,10-16} function Form() { const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); - // ✅ Good: This logic should run because the component was displayed + // ✅ Good: This logic should run because the Component was displayed useEffect(() => { post('/analytics/event', { eventName: 'visit_form' }); }, []); @@ -344,7 +344,7 @@ function Form() { const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); - // ✅ Good: This logic runs because the component was displayed + // ✅ Good: This logic runs because the Component was displayed useEffect(() => { post('/analytics/event', { eventName: 'visit_form' }); }, []); @@ -358,7 +358,7 @@ function Form() { } ``` -When you choose whether to put some logic into an event handler or an Effect, the main question you need to answer is _what kind of logic_ it is from the user's perspective. If this logic is caused by a particular interaction, keep it in the event handler. If it's caused by the user _seeing_ the component on the screen, keep it in the Effect. +When you choose whether to put some logic into an event handler or an Effect, the main question you need to answer is _what kind of logic_ it is from the user's perspective. If this logic is caused by a particular interaction, keep it in the event handler. If it's caused by the user _seeing_ the Component on the screen, keep it in the Effect. ### Chains of computations {/*chains-of-computations*/} @@ -408,7 +408,7 @@ function Game() { There are two problems with this code. -One problem is that it is very inefficient: the component (and its children) have to re-render between each `set` call in the chain. In the example above, in the worst case (`setCard` → render → `setGoldCardCount` → render → `setRound` → render → `setIsGameOver` → render) there are three unnecessary re-renders of the tree below. +One problem is that it is very inefficient: the Component (and its children) have to re-render between each `set` call in the chain. In the example above, in the worst case (`setCard` → render → `setGoldCardCount` → render → `setRound` → render → `setIsGameOver` → render) there are three unnecessary re-renders of the tree below. Even if it weren't slow, as your code evolves, you will run into cases where the "chain" you wrote doesn't fit the new requirements. Imagine you are adding a way to step through the history of the game moves. You'd do it by updating each state variable to a value from the past. However, setting the `card` state to a value from the past would trigger the Effect chain again and change the data you're showing. Such code is often rigid and fragile. @@ -469,9 +469,9 @@ function App() { } ``` -However, you'll quickly discover that it [runs twice in development.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) This can cause issues--for example, maybe it invalidates the authentication token because the function wasn't designed to be called twice. In general, your components should be resilient to being remounted. This includes your top-level `App` component. +However, you'll quickly discover that it [runs twice in development.](/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development) This can cause issues--for example, maybe it invalidates the authentication token because the function wasn't designed to be called twice. In general, your Components should be resilient to being remounted. This includes your top-level `App` component. -Although it may not ever get remounted in practice in production, following the same constraints in all components makes it easier to move and reuse code. If some logic must run *once per app load* rather than *once per component mount*, add a top-level variable to track whether it has already executed: +Although it may not ever get remounted in practice in production, following the same constraints in all Components makes it easier to move and reuse code. If some logic must run *once per app load* rather than *once per Component mount*, add a top-level variable to track whether it has already executed: ```js {1,5-6,10} let didInit = false; @@ -503,11 +503,11 @@ function App() { } ``` -Code at the top level runs once when your component is imported--even if it doesn't end up being rendered. To avoid slowdown or surprising behavior when importing arbitrary components, don't overuse this pattern. Keep app-wide initialization logic to root component modules like `App.js` or in your application's entry point. +Code at the top level runs once when your Component is imported--even if it doesn't end up being rendered. To avoid slowdown or surprising behavior when importing arbitrary components, don't overuse this pattern. Keep app-wide initialization logic to root Component modules like `App.js` or in your application's entry point. -### Notifying parent components about state changes {/*notifying-parent-components-about-state-changes*/} +### Notifying parent Components about state changes {/*notifying-parent-components-about-state-changes*/} -Let's say you're writing a `Toggle` component with an internal `isOn` state which can be either `true` or `false`. There are a few different ways to toggle it (by clicking or dragging). You want to notify the parent component whenever the `Toggle` internal state changes, so you expose an `onChange` event and call it from an Effect: +Let's say you're writing a `Toggle` Component with an internal `isOn` state which can be either `true` or `false`. There are a few different ways to toggle it (by clicking or dragging). You want to notify the parent Component whenever the `Toggle` internal state changes, so you expose an `onChange` event and call it from an Effect: ```js {4-7} function Toggle({ onChange }) { @@ -534,9 +534,9 @@ function Toggle({ onChange }) { } ``` -Like earlier, this is not ideal. The `Toggle` updates its state first, and React updates the screen. Then React runs the Effect, which calls the `onChange` function passed from a parent component. Now the parent component will update its own state, starting another render pass. It would be better to do everything in a single pass. +Like earlier, this is not ideal. The `Toggle` updates its state first, and React updates the screen. Then React runs the Effect, which calls the `onChange` function passed from a parent component. Now the parent Component will update its own state, starting another render pass. It would be better to do everything in a single pass. -Delete the Effect and instead update the state of *both* components within the same event handler: +Delete the Effect and instead update the state of *both* Components within the same event handler: ```js {5-7,11,16,18} function Toggle({ onChange }) { @@ -564,12 +564,12 @@ function Toggle({ onChange }) { } ``` -With this approach, both the `Toggle` component and its parent component update their state during the event. React [batches updates](/learn/queueing-a-series-of-state-updates) from different components together, so there will only be one render pass. +With this approach, both the `Toggle` Component and its parent Component update their state during the event. React [batches updates](/learn/queueing-a-series-of-state-updates) from different Components together, so there will only be one render pass. You might also be able to remove the state altogether, and instead receive `isOn` from the parent component: ```js {1,2} -// ✅ Also good: the component is fully controlled by its parent +// ✅ Also good: the Component is fully controlled by its parent function Toggle({ isOn, onChange }) { function handleClick() { onChange(!isOn); @@ -587,11 +587,11 @@ function Toggle({ isOn, onChange }) { } ``` -["Lifting state up"](/learn/sharing-state-between-components) lets the parent component fully control the `Toggle` by toggling the parent's own state. This means the parent component will have to contain more logic, but there will be less state overall to worry about. Whenever you try to keep two different state variables synchronized, try lifting state up instead! +["Lifting state up"](/learn/sharing-state-between-components) lets the parent Component fully control the `Toggle` by toggling the parent's own state. This means the parent Component will have to contain more logic, but there will be less state overall to worry about. Whenever you try to keep two different state variables synchronized, try lifting state up instead! ### Passing data to the parent {/*passing-data-to-the-parent*/} -This `Child` component fetches some data and then passes it to the `Parent` component in an Effect: +This `Child` Component fetches some data and then passes it to the `Parent` Component in an Effect: ```js {9-14} function Parent() { @@ -612,7 +612,7 @@ function Child({ onFetched }) { } ``` -In React, data flows from the parent components to their children. When you see something wrong on the screen, you can trace where the information comes from by going up the component chain until you find which component passes the wrong prop or has the wrong state. When child components update the state of their parent components in Effects, the data flow becomes very difficult to trace. Since both the child and the parent need the same data, let the parent component fetch that data, and *pass it down* to the child instead: +In React, data flows from the parent Components to their children. When you see something wrong on the screen, you can trace where the information comes from by going up the Component chain until you find which Component passes the wrong prop or has the wrong state. When child Components update the state of their parent Components in Effects, the data flow becomes very difficult to trace. Since both the child and the parent need the same data, let the parent Component fetch that data, and *pass it down* to the child instead: ```js {4-5} function Parent() { @@ -631,7 +631,7 @@ This is simpler and keeps the data flow predictable: the data flows down from th ### Subscribing to an external store {/*subscribing-to-an-external-store*/} -Sometimes, your components may need to subscribe to some data outside of the React state. This data could be from a third-party library or a built-in browser API. Since this data can change without React's knowledge, you need to manually subscribe your components to it. This is often done with an Effect, for example: +Sometimes, your Components may need to subscribe to some data outside of the React state. This data could be from a third-party library or a built-in browser API. Since this data can change without React's knowledge, you need to manually subscribe your Components to it. This is often done with an Effect, for example: ```js {2-17} function useOnlineStatus() { @@ -660,7 +660,7 @@ function ChatIndicator() { } ``` -Here, the component subscribes to an external data store (in this case, the browser `navigator.onLine` API). Since this API does not exist on the server (so it can't be used for the initial HTML), initially the state is set to `true`. Whenever the value of that data store changes in the browser, the component updates its state. +Here, the Component subscribes to an external data store (in this case, the browser `navigator.onLine` API). Since this API does not exist on the server (so it can't be used for the initial HTML), initially the state is set to `true`. Whenever the value of that data store changes in the browser, the Component updates its state. Although it's common to use Effects for this, React has a purpose-built Hook for subscribing to an external store that is preferred instead. Delete the Effect and replace it with a call to [`useSyncExternalStore`](/reference/react/useSyncExternalStore): @@ -718,7 +718,7 @@ You *don't* need to move this fetch to an event handler. This might seem like a contradiction with the earlier examples where you needed to put the logic into the event handlers! However, consider that it's not *the typing event* that's the main reason to fetch. Search inputs are often prepopulated from the URL, and the user might navigate Back and Forward without touching the input. -It doesn't matter where `page` and `query` come from. While this component is visible, you want to keep `results` [synchronized](/learn/synchronizing-with-effects) with data from the network for the current `page` and `query`. This is why it's an Effect. +It doesn't matter where `page` and `query` come from. While this Component is visible, you want to keep `results` [synchronized](/learn/synchronizing-with-effects) with data from the network for the current `page` and `query`. This is why it's an Effect. However, the code above has a bug. Imagine you type `"hello"` fast. Then the `query` will change from `"h"`, to `"he"`, `"hel"`, `"hell"`, and `"hello"`. This will kick off separate fetches, but there is no guarantee about which order the responses will arrive in. For example, the `"hell"` response may arrive *after* the `"hello"` response. Since it will call `setResults()` last, you will be displaying the wrong search results. This is called a ["race condition"](https://en.wikipedia.org/wiki/Race_condition): two different requests "raced" against each other and came in a different order than you expected. @@ -794,9 +794,9 @@ In general, whenever you have to resort to writing Effects, keep an eye out for - If you can calculate something during render, you don't need an Effect. - To cache expensive calculations, add `useMemo` instead of `useEffect`. -- To reset the state of an entire component tree, pass a different `key` to it. +- To reset the state of an entire Component tree, pass a different `key` to it. - To reset a particular bit of state in response to a prop change, set it during rendering. -- Code that runs because a component was *displayed* should be in Effects, the rest should be in events. +- Code that runs because a Component was *displayed* should be in Effects, the rest should be in events. - If you need to update the state of several components, it's better to do it during a single event. - Whenever you try to synchronize state variables in different components, consider lifting state up. - You can fetch data with Effects, but you need to implement cleanup to avoid race conditions. @@ -809,7 +809,7 @@ In general, whenever you have to resort to writing Effects, keep an eye out for The `TodoList` below displays a list of todos. When the "Show only active todos" checkbox is ticked, completed todos are not displayed in the list. Regardless of which todos are visible, the footer displays the count of todos that are not yet completed. -Simplify this component by removing all the unnecessary state and Effects. +Simplify this Component by removing all the unnecessary state and Effects. <Sandpack> @@ -1266,13 +1266,13 @@ input { margin-top: 10px; } </Sandpack> -This approach satisfies the requirements too. When you type into the input, only the `text` state variable updates. Since the `text` state variable is in the child `NewTodo` component, the parent `TodoList` component won't get re-rendered. This is why `getVisibleTodos()` doesn't get called when you type. (It would still be called if the `TodoList` re-renders for another reason.) +This approach satisfies the requirements too. When you type into the input, only the `text` state variable updates. Since the `text` state variable is in the child `NewTodo` component, the parent `TodoList` Component won't get re-rendered. This is why `getVisibleTodos()` doesn't get called when you type. (It would still be called if the `TodoList` re-renders for another reason.) </Solution> #### Reset state without Effects {/*reset-state-without-effects*/} -This `EditContact` component receives a contact object shaped like `{ id, name, email }` as the `savedContact` prop. Try editing the name and email input fields. When you press Save, the contact's button above the form updates to the edited name. When you press Reset, any pending changes in the form are discarded. Play around with this UI to get a feel for it. +This `EditContact` Component receives a contact object shaped like `{ id, name, email }` as the `savedContact` prop. Try editing the name and email input fields. When you press Save, the contact's button above the form updates to the edited name. When you press Reset, any pending changes in the form are discarded. Play around with this UI to get a feel for it. When you select a contact with the buttons at the top, the form resets to reflect that contact's details. This is done with an Effect inside `EditContact.js`. Remove this Effect. Find another way to reset the form when `savedContact.id` changes. @@ -1438,7 +1438,7 @@ It would be nice if there was a way to tell React that when `savedContact.id` is <Solution> -Split the `EditContact` component in two. Move all the form state into the inner `EditForm` component. Export the outer `EditContact` component, and make it pass `savedContact.id` as the `key` to the inner `EditForm` component. As a result, the inner `EditForm` component resets all of the form state and recreates the DOM whenever you select a different contact. +Split the `EditContact` Component in two. Move all the form state into the inner `EditForm` component. Export the outer `EditContact` component, and make it pass `savedContact.id` as the `key` to the inner `EditForm` component. As a result, the inner `EditForm` Component resets all of the form state and recreates the DOM whenever you select a different contact. <Sandpack> @@ -1602,7 +1602,7 @@ button { #### Submit a form without Effects {/*submit-a-form-without-effects*/} -This `Form` component lets you send a message to a friend. When you submit the form, the `showForm` state variable is set to `false`. This triggers an Effect calling `sendMessage(message)`, which sends the message (you can see it in the console). After the message is sent, you see a "Thank you" dialog with an "Open chat" button that lets you get back to the form. +This `Form` Component lets you send a message to a friend. When you submit the form, the `showForm` state variable is set to `false`. This triggers an Effect calling `sendMessage(message)`, which sends the message (you can see it in the console). After the message is sent, you see a "Thank you" dialog with an "Open chat" button that lets you get back to the form. Your app's users are sending way too many messages. To make chatting a little bit more difficult, you've decided to show the "Thank you" dialog *first* rather than the form. Change the `showForm` state variable to initialize to `false` instead of `true`. As soon as you make that change, the console will show that an empty message was sent. Something in this logic is wrong! diff --git a/src/content/learn/your-first-component.md b/src/content/learn/your-first-component.md index 17fa01e98c4..637fcd6bba2 100644 --- a/src/content/learn/your-first-component.md +++ b/src/content/learn/your-first-component.md @@ -10,8 +10,8 @@ title: Your First Component <YouWillLearn> -* What a component is -* What role components play in a React application +* What a Component is +* What role Components play in a React application * How to write your first React component </YouWillLearn> @@ -33,9 +33,9 @@ On the Web, HTML lets us create rich structured documents with its built-in set This markup represents this article `<article>`, its heading `<h1>`, and an (abbreviated) table of contents as an ordered list `<ol>`. Markup like this, combined with CSS for style, and JavaScript for interactivity, lies behind every sidebar, avatar, modal, dropdown—every piece of UI you see on the Web. -React lets you combine your markup, CSS, and JavaScript into custom "components", **reusable UI elements for your app.** The table of contents code you saw above could be turned into a `<TableOfContents />` component you could render on every page. Under the hood, it still uses the same HTML tags like `<article>`, `<h1>`, etc. +React lets you combine your markup, CSS, and JavaScript into custom "components", **reusable UI elements for your app.** The table of contents code you saw above could be turned into a `<TableOfContents />` Component you could render on every page. Under the hood, it still uses the same HTML tags like `<article>`, `<h1>`, etc. -Just like with HTML tags, you can compose, order and nest components to design whole pages. For example, the documentation page you're reading is made out of React components: +Just like with HTML tags, you can compose, order and nest Components to design whole pages. For example, the documentation page you're reading is made out of React components: ```js <PageLayout> @@ -51,11 +51,11 @@ Just like with HTML tags, you can compose, order and nest components to design w </PageLayout> ``` -As your project grows, you will notice that many of your designs can be composed by reusing components you already wrote, speeding up your development. Our table of contents above could be added to any screen with `<TableOfContents />`! You can even jumpstart your project with the thousands of components shared by the React open source community like [Chakra UI](https://chakra-ui.com/) and [Material UI.](https://material-ui.com/) +As your project grows, you will notice that many of your designs can be composed by reusing Components you already wrote, speeding up your development. Our table of contents above could be added to any screen with `<TableOfContents />`! You can even jumpstart your project with the thousands of Components shared by the React open source community like [Chakra UI](https://chakra-ui.com/) and [Material UI.](https://material-ui.com/) -## Defining a component {/*defining-a-component*/} +## Defining a Component {/*defining-a-component*/} -Traditionally when creating web pages, web developers marked up their content and then added interaction by sprinkling on some JavaScript. This worked great when interaction was a nice-to-have on the web. Now it is expected for many sites and all apps. React puts interactivity first while still using the same technology: **a React component is a JavaScript function that you can _sprinkle with markup_.** Here's what that looks like (you can edit the example below): +Traditionally when creating web pages, web developers marked up their content and then added interaction by sprinkling on some JavaScript. This worked great when interaction was a nice-to-have on the web. Now it is expected for many sites and all apps. React puts interactivity first while still using the same technology: **a React Component is a JavaScript function that you can _sprinkle with markup_.** Here's what that looks like (you can edit the example below): <Sandpack> @@ -78,7 +78,7 @@ img { height: 200px; } And here's how to build a component: -### Step 1: Export the component {/*step-1-export-the-component*/} +### Step 1: Export the Component {/*step-1-export-the-component*/} The `export default` prefix is a [standard JavaScript syntax](https://developer.mozilla.org/docs/web/javascript/reference/statements/export) (not specific to React). It lets you mark the main function in a file so that you can later import it from other files. (More on importing in [Importing and Exporting Components](/learn/importing-and-exporting-components)!) @@ -88,13 +88,13 @@ With `function Profile() { }` you define a JavaScript function with the name `Pr <Pitfall> -React components are regular JavaScript functions, but **their names must start with a capital letter** or they won't work! +React Components are regular JavaScript functions, but **their names must start with a capital letter** or they won't work! </Pitfall> ### Step 3: Add markup {/*step-3-add-markup*/} -The component returns an `<img />` tag with `src` and `alt` attributes. `<img />` is written like HTML, but it is actually JavaScript under the hood! This syntax is called [JSX](/learn/writing-markup-with-jsx), and it lets you embed markup inside JavaScript. +The Component returns an `<img />` tag with `src` and `alt` attributes. `<img />` is written like HTML, but it is actually JavaScript under the hood! This syntax is called [JSX](/learn/writing-markup-with-jsx), and it lets you embed markup inside JavaScript. Return statements can be written all on one line, as in this component: @@ -118,9 +118,9 @@ Without parentheses, any code on the lines after `return` [will be ignored](http </Pitfall> -## Using a component {/*using-a-component*/} +## Using a Component {/*using-a-component*/} -Now that you've defined your `Profile` component, you can nest it inside other components. For example, you can export a `Gallery` component that uses multiple `Profile` components: +Now that you've defined your `Profile` component, you can nest it inside other components. For example, you can export a `Gallery` Component that uses multiple `Profile` components: <Sandpack> @@ -157,7 +157,7 @@ img { margin: 0 10px 10px 0; height: 90px; } Notice the difference in casing: * `<section>` is lowercase, so React knows we refer to an HTML tag. -* `<Profile />` starts with a capital `P`, so React knows that we want to use our component called `Profile`. +* `<Profile />` starts with a capital `P`, so React knows that we want to use our Component called `Profile`. And `Profile` contains even more HTML: `<img />`. In the end, this is what the browser sees: @@ -170,11 +170,11 @@ And `Profile` contains even more HTML: `<img />`. In the end, this is what the b </section> ``` -### Nesting and organizing components {/*nesting-and-organizing-components*/} +### Nesting and organizing Components {/*nesting-and-organizing-components*/} -Components are regular JavaScript functions, so you can keep multiple components in the same file. This is convenient when components are relatively small or tightly related to each other. If this file gets crowded, you can always move `Profile` to a separate file. You will learn how to do this shortly on the [page about imports.](/learn/importing-and-exporting-components) +Components are regular JavaScript functions, so you can keep multiple Components in the same file. This is convenient when Components are relatively small or tightly related to each other. If this file gets crowded, you can always move `Profile` to a separate file. You will learn how to do this shortly on the [page about imports.](/learn/importing-and-exporting-components) -Because the `Profile` components are rendered inside `Gallery`—even several times!—we can say that `Gallery` is a **parent component,** rendering each `Profile` as a "child". This is part of the magic of React: you can define a component once, and then use it in as many places and as many times as you like. +Because the `Profile` Components are rendered inside `Gallery`—even several times!—we can say that `Gallery` is a **parent component,** rendering each `Profile` as a "child". This is part of the magic of React: you can define a Component once, and then use it in as many places and as many times as you like. <Pitfall> @@ -182,7 +182,7 @@ Components can render other components, but **you must never nest their definiti ```js {2-5} export default function Gallery() { - // 🔴 Never define a component inside another component! + // 🔴 Never define a Component inside another component! function Profile() { // ... } @@ -190,20 +190,20 @@ export default function Gallery() { } ``` -The snippet above is [very slow and causes bugs.](/learn/preserving-and-resetting-state#different-components-at-the-same-position-reset-state) Instead, define every component at the top level: +The snippet above is [very slow and causes bugs.](/learn/preserving-and-resetting-state#different-components-at-the-same-position-reset-state) Instead, define every Component at the top level: ```js {5-8} export default function Gallery() { // ... } -// ✅ Declare components at the top level +// ✅ Declare Components at the top level function Profile() { // ... } ``` -When a child component needs some data from a parent, [pass it by props](/learn/passing-props-to-a-component) instead of nesting definitions. +When a child Component needs some data from a parent, [pass it by props](/learn/passing-props-to-a-component) instead of nesting definitions. </Pitfall> @@ -211,13 +211,13 @@ When a child component needs some data from a parent, [pass it by props](/learn/ #### Components all the way down {/*components-all-the-way-down*/} -Your React application begins at a "root" component. Usually, it is created automatically when you start a new project. For example, if you use [CodeSandbox](https://codesandbox.io/) or if you use the framework [Next.js](https://nextjs.org/), the root component is defined in `pages/index.js`. In these examples, you've been exporting root components. +Your React application begins at a "root" component. Usually, it is created automatically when you start a new project. For example, if you use [CodeSandbox](https://codesandbox.io/) or if you use the framework [Next.js](https://nextjs.org/), the root Component is defined in `pages/index.js`. In these examples, you've been exporting root components. -Most React apps use components all the way down. This means that you won't only use components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once. +Most React apps use Components all the way down. This means that you won't only use Components for reusable pieces like buttons, but also for larger pieces like sidebars, lists, and ultimately, complete pages! Components are a handy way to organize UI code and markup, even if some of them are only used once. [React-based frameworks](/learn/start-a-new-react-project) take this a step further. Instead of using an empty HTML file and letting React "take over" managing the page with JavaScript, they *also* generate the HTML automatically from your React components. This allows your app to show some content before the JavaScript code loads. -Still, many websites only use React to [add interactivity to existing HTML pages.](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page) They have many root components instead of a single one for the entire page. You can use as much—or as little—React as you need. +Still, many websites only use React to [add interactivity to existing HTML pages.](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page) They have many root Components instead of a single one for the entire page. You can use as much—or as little—React as you need. </DeepDive> @@ -227,7 +227,7 @@ You've just gotten your first taste of React! Let's recap some key points. * React lets you create components, **reusable UI elements for your app.** * In a React app, every piece of UI is a component. -* React components are regular JavaScript functions except: +* React Components are regular JavaScript functions except: 1. Their names always begin with a capital letter. 2. They return JSX markup. @@ -238,9 +238,9 @@ You've just gotten your first taste of React! Let's recap some key points. <Challenges> -#### Export the component {/*export-the-component*/} +#### Export the Component {/*export-the-component*/} -This sandbox doesn't work because the root component is not exported: +This sandbox doesn't work because the root Component is not exported: <Sandpack> @@ -318,7 +318,7 @@ img { height: 180px; } <Solution> -You can fix this component by moving the return statement to one line like so: +You can fix this Component by moving the return statement to one line like so: <Sandpack> @@ -359,7 +359,7 @@ img { height: 180px; } #### Spot the mistake {/*spot-the-mistake*/} -Something's wrong with how the `Profile` component is declared and used. Can you spot the mistake? (Try to remember how React distinguishes components from the regular HTML tags!) +Something's wrong with how the `Profile` Component is declared and used. Can you spot the mistake? (Try to remember how React distinguishes Components from the regular HTML tags!) <Sandpack> @@ -393,7 +393,7 @@ img { margin: 0 10px 10px 0; height: 90px; } <Solution> -React component names must start with a capital letter. +React Component names must start with a capital letter. Change `function profile()` to `function Profile()`, and then change every `<profile />` to `<Profile />`: @@ -429,14 +429,14 @@ img { margin: 0 10px 10px 0; } </Solution> -#### Your own component {/*your-own-component*/} +#### Your own Component {/*your-own-component*/} -Write a component from scratch. You can give it any valid name and return any markup. If you're out of ideas, you can write a `Congratulations` component that shows `<h1>Good job!</h1>`. Don't forget to export it! +Write a Component from scratch. You can give it any valid name and return any markup. If you're out of ideas, you can write a `Congratulations` Component that shows `<h1>Good job!</h1>`. Don't forget to export it! <Sandpack> ```js -// Write your component below! +// Write your Component below! ``` diff --git a/src/content/reference/react-dom/client/createRoot.md b/src/content/reference/react-dom/client/createRoot.md index afddb4177d3..a51b4004076 100644 --- a/src/content/reference/react-dom/client/createRoot.md +++ b/src/content/reference/react-dom/client/createRoot.md @@ -4,7 +4,7 @@ title: createRoot <Intro> -`createRoot` lets you create a root to display React components inside a browser DOM node. +`createRoot` lets you create a root to display React Components inside a browser DOM node. ```js const root = createRoot(domNode, options?) @@ -29,7 +29,7 @@ const domNode = document.getElementById('root'); const root = createRoot(domNode); ``` -React will create a root for the `domNode`, and take over managing the DOM inside it. After you've created a root, you need to call [`root.render`](#root-render) to display a React component inside of it: +React will create a root for the `domNode`, and take over managing the DOM inside it. After you've created a root, you need to call [`root.render`](#root-render) to display a React Component inside of it: ```js root.render(<App />); @@ -55,7 +55,7 @@ An app fully built with React will usually only have one `createRoot` call for i #### Caveats {/*caveats*/} * If your app is server-rendered, using `createRoot()` is not supported. Use [`hydrateRoot()`](/reference/react-dom/client/hydrateRoot) instead. * You'll likely have only one `createRoot` call in your app. If you use a framework, it might do this call for you. -* When you want to render a piece of JSX in a different part of the DOM tree that isn't a child of your component (for example, a modal or a tooltip), use [`createPortal`](/reference/react-dom/createPortal) instead of `createRoot`. +* When you want to render a piece of JSX in a different part of the DOM tree that isn't a child of your Component (for example, a modal or a tooltip), use [`createPortal`](/reference/react-dom/createPortal) instead of `createRoot`. --- @@ -82,7 +82,7 @@ React will display `<App />` in the `root`, and take over managing the DOM insid #### Caveats {/*root-render-caveats*/} -* The first time you call `root.render`, React will clear all the existing HTML content inside the React root before rendering the React component into it. +* The first time you call `root.render`, React will clear all the existing HTML content inside the React root before rendering the React Component into it. * If your root's DOM node contains HTML generated by React on the server or during the build, use [`hydrateRoot()`](/reference/react-dom/client/hydrateRoot) instead, which attaches the event handlers to the existing HTML. @@ -100,9 +100,9 @@ root.unmount(); An app fully built with React will usually not have any calls to `root.unmount`. -This is mostly useful if your React root's DOM node (or any of its ancestors) may get removed from the DOM by some other code. For example, imagine a jQuery tab panel that removes inactive tabs from the DOM. If a tab gets removed, everything inside it (including the React roots inside) would get removed from the DOM as well. In that case, you need to tell React to "stop" managing the removed root's content by calling `root.unmount`. Otherwise, the components inside the removed root won't know to clean up and free up global resources like subscriptions. +This is mostly useful if your React root's DOM node (or any of its ancestors) may get removed from the DOM by some other code. For example, imagine a jQuery tab panel that removes inactive tabs from the DOM. If a tab gets removed, everything inside it (including the React roots inside) would get removed from the DOM as well. In that case, you need to tell React to "stop" managing the removed root's content by calling `root.unmount`. Otherwise, the Components inside the removed root won't know to clean up and free up global resources like subscriptions. -Calling `root.unmount` will unmount all the components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree. +Calling `root.unmount` will unmount all the Components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree. #### Parameters {/*root-unmount-parameters*/} @@ -116,7 +116,7 @@ Calling `root.unmount` will unmount all the components in the root and "detach" #### Caveats {/*root-unmount-caveats*/} -* Calling `root.unmount` will unmount all the components in the tree and "detach" React from the root DOM node. +* Calling `root.unmount` will unmount all the Components in the tree and "detach" React from the root DOM node. * Once you call `root.unmount` you cannot call `root.render` again on the same root. Attempting to call `root.render` on an unmounted root will throw a "Cannot update an unmounted root" error. However, you can create a new root for the same DOM node after the previous root for that node has been unmounted. @@ -188,7 +188,7 @@ function Counter() { **If your app is fully built with React, you shouldn't need to create any more roots, or to call [`root.render`](#root-render) again.** -From this point on, React will manage the DOM of your entire app. To add more components, [nest them inside the `App` component.](/learn/importing-and-exporting-components) When you need to update the UI, each of your components can do this by [using state.](/reference/react/useState) When you need to display extra content like a modal or a tooltip outside the DOM node, [render it with a portal.](/reference/react-dom/createPortal) +From this point on, React will manage the DOM of your entire app. To add more components, [nest them inside the `App` component.](/learn/importing-and-exporting-components) When you need to update the UI, each of your Components can do this by [using state.](/reference/react/useState) When you need to display extra content like a modal or a tooltip outside the DOM node, [render it with a portal.](/reference/react-dom/createPortal) <Note> @@ -198,7 +198,7 @@ When your HTML is empty, the user sees a blank page until the app's JavaScript c <div id="root"></div> ``` -This can feel very slow! To solve this, you can generate the initial HTML from your components [on the server or during the build.](/reference/react-dom/server) Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend [using a framework](/learn/start-a-new-react-project#production-grade-react-frameworks) that does this optimization out of the box. Depending on when it runs, this is called *server-side rendering (SSR)* or *static site generation (SSG).* +This can feel very slow! To solve this, you can generate the initial HTML from your Components [on the server or during the build.](/reference/react-dom/server) Then your visitors can read text, see images, and click links before any of the JavaScript code loads. We recommend [using a framework](/learn/start-a-new-react-project#production-grade-react-frameworks) that does this optimization out of the box. Depending on when it runs, this is called *server-side rendering (SSR)* or *static site generation (SSG).* </Note> @@ -214,7 +214,7 @@ This can feel very slow! To solve this, you can generate the initial HTML from y If your page [isn't fully built with React](/learn/add-react-to-an-existing-project#using-react-for-a-part-of-your-existing-page), you can call `createRoot` multiple times to create a root for each top-level piece of UI managed by React. You can display different content in each root by calling [`root.render`.](#root-render) -Here, two different React components are rendered into two DOM nodes defined in the `index.html` file: +Here, two different React Components are rendered into two DOM nodes defined in the `index.html` file: <Sandpack> @@ -303,13 +303,13 @@ To remove the React tree from the DOM node and clean up all the resources used b root.unmount(); ``` -This is mostly useful if your React components are inside an app written in a different framework. +This is mostly useful if your React Components are inside an app written in a different framework. --- -### Updating a root component {/*updating-a-root-component*/} +### Updating a root Component {/*updating-a-root-component*/} -You can call `render` more than once on the same root. As long as the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive: +You can call `render` more than once on the same root. As long as the Component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive: <Sandpack> @@ -340,7 +340,7 @@ export default function App({counter}) { </Sandpack> -It is uncommon to call `render` multiple times. Usually, your components will [update state](/reference/react/useState) instead. +It is uncommon to call `render` multiple times. Usually, your Components will [update state](/reference/react/useState) instead. --- ## Troubleshooting {/*troubleshooting*/} diff --git a/src/content/reference/react-dom/client/hydrateRoot.md b/src/content/reference/react-dom/client/hydrateRoot.md index c137cdda9d5..c0201a5bded 100644 --- a/src/content/reference/react-dom/client/hydrateRoot.md +++ b/src/content/reference/react-dom/client/hydrateRoot.md @@ -4,7 +4,7 @@ title: hydrateRoot <Intro> -`hydrateRoot` lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server) +`hydrateRoot` lets you display React Components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server) ```js const root = hydrateRoot(domNode, reactNode, options?) @@ -60,7 +60,7 @@ React will attach to the HTML that exists inside the `domNode`, and take over ma ### `root.render(reactNode)` {/*root-render*/} -Call `root.render` to update a React component inside a hydrated React root for a browser DOM element. +Call `root.render` to update a React Component inside a hydrated React root for a browser DOM element. ```js root.render(<App />); @@ -95,9 +95,9 @@ root.unmount(); An app fully built with React will usually not have any calls to `root.unmount`. -This is mostly useful if your React root's DOM node (or any of its ancestors) may get removed from the DOM by some other code. For example, imagine a jQuery tab panel that removes inactive tabs from the DOM. If a tab gets removed, everything inside it (including the React roots inside) would get removed from the DOM as well. You need to tell React to "stop" managing the removed root's content by calling `root.unmount`. Otherwise, the components inside the removed root won't clean up and free up resources like subscriptions. +This is mostly useful if your React root's DOM node (or any of its ancestors) may get removed from the DOM by some other code. For example, imagine a jQuery tab panel that removes inactive tabs from the DOM. If a tab gets removed, everything inside it (including the React roots inside) would get removed from the DOM as well. You need to tell React to "stop" managing the removed root's content by calling `root.unmount`. Otherwise, the Components inside the removed root won't clean up and free up resources like subscriptions. -Calling `root.unmount` will unmount all the components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree. +Calling `root.unmount` will unmount all the Components in the root and "detach" React from the root DOM node, including removing any event handlers or state in the tree. #### Parameters {/*root-unmount-parameters*/} @@ -111,7 +111,7 @@ Calling `root.unmount` will unmount all the components in the root and "detach" #### Caveats {/*root-unmount-caveats*/} -* Calling `root.unmount` will unmount all the components in the tree and "detach" React from the root DOM node. +* Calling `root.unmount` will unmount all the Components in the tree and "detach" React from the root DOM node. * Once you call `root.unmount` you cannot call `root.render` again on the root. Attempting to call `root.render` on an unmounted root will throw a "Cannot update an unmounted root" error. @@ -178,7 +178,7 @@ function Counter() { </Sandpack> -You shouldn't need to call `hydrateRoot` again or to call it in more places. From this point on, React will be managing the DOM of your application. To update the UI, your components will [use state](/reference/react/useState) instead. +You shouldn't need to call `hydrateRoot` again or to call it in more places. From this point on, React will be managing the DOM of your application. To update the UI, your Components will [use state](/reference/react/useState) instead. <Pitfall> @@ -318,17 +318,17 @@ This way the initial render pass will render the same content as the server, avo <Pitfall> -This approach makes hydration slower because your components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may also feel jarring to the user. +This approach makes hydration slower because your Components have to render twice. Be mindful of the user experience on slow connections. The JavaScript code may load significantly later than the initial HTML render, so rendering a different UI immediately after hydration may also feel jarring to the user. </Pitfall> --- -### Updating a hydrated root component {/*updating-a-hydrated-root-component*/} +### Updating a hydrated root Component {/*updating-a-hydrated-root-component*/} After the root has finished hydrating, you can call [`root.render`](#root-render) to update the root React component. **Unlike with [`createRoot`](/reference/react-dom/client/createRoot), you don't usually need to do this because the initial content was already rendered as HTML.** -If you call `root.render` at some point after hydration, and the component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive: +If you call `root.render` at some point after hydration, and the Component tree structure matches up with what was previously rendered, React will [preserve the state.](/learn/preserving-and-resetting-state) Notice how you can type in the input, which means that the updates from repeated `render` calls every second in this example are not destructive: <Sandpack> @@ -370,4 +370,4 @@ export default function App({counter}) { </Sandpack> -It is uncommon to call [`root.render`](#root-render) on a hydrated root. Usually, you'll [update state](/reference/react/useState) inside one of the components instead. +It is uncommon to call [`root.render`](#root-render) on a hydrated root. Usually, you'll [update state](/reference/react/useState) inside one of the Components instead. diff --git a/src/content/reference/react-dom/client/index.md b/src/content/reference/react-dom/client/index.md index 89f48212fad..e6618112a9e 100644 --- a/src/content/reference/react-dom/client/index.md +++ b/src/content/reference/react-dom/client/index.md @@ -4,7 +4,7 @@ title: Client React DOM APIs <Intro> -The `react-dom/client` APIs let you render React components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/start-a-new-react-project#production-grade-react-frameworks) may call them for you. Most of your components don't need to import or use them. +The `react-dom/client` APIs let you render React Components on the client (in the browser). These APIs are typically used at the top level of your app to initialize your React tree. A [framework](/learn/start-a-new-react-project#production-grade-react-frameworks) may call them for you. Most of your Components don't need to import or use them. </Intro> @@ -12,8 +12,8 @@ The `react-dom/client` APIs let you render React components on the client (in th ## Client APIs {/*client-apis*/} -* [`createRoot`](/reference/react-dom/client/createRoot) lets you create a root to display React components inside a browser DOM node. -* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) lets you display React components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server) +* [`createRoot`](/reference/react-dom/client/createRoot) lets you create a root to display React Components inside a browser DOM node. +* [`hydrateRoot`](/reference/react-dom/client/hydrateRoot) lets you display React Components inside a browser DOM node whose HTML content was previously generated by [`react-dom/server`.](/reference/react-dom/server) --- diff --git a/src/content/reference/react-dom/components/common.md b/src/content/reference/react-dom/components/common.md index 610742735a3..93fe7ed006c 100644 --- a/src/content/reference/react-dom/components/common.md +++ b/src/content/reference/react-dom/components/common.md @@ -1,5 +1,5 @@ --- -title: "Common components (e.g. <div>)" +title: "Common Components (e.g. <div>)" --- <Intro> @@ -14,7 +14,7 @@ All built-in browser components, such as [`<div>`](https://developer.mozilla.org ## Reference {/*reference*/} -### Common components (e.g. `<div>`) {/*common*/} +### Common Components (e.g. `<div>`) {/*common*/} ```js <div className="wrapper">Some content</div> @@ -52,7 +52,7 @@ These standard DOM props are also supported for all built-in components: * [`htmlFor`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor): A string. For [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label) and [`<output>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output), lets you [associate the label with some control.](/reference/react-dom/components/input#providing-a-label-for-an-input) Same as [`for` HTML attribute.](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/for) React uses the standard DOM property names (`htmlFor`) instead of HTML attribute names. * [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden): A boolean or a string. Specifies whether the element should be hidden. * [`id`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id): A string. Specifies a unique identifier for this element, which can be used to find it later or connect it with other elements. Generate it with [`useId`](/reference/react/useId) to avoid clashes between multiple instances of the same component. -* [`is`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is): A string. If specified, the component will behave like a [custom element.](/reference/react-dom/components#custom-html-elements) +* [`is`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/is): A string. If specified, the Component will behave like a [custom element.](/reference/react-dom/components#custom-html-elements) * [`inputMode`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode): A string. Specifies what kind of keyboard to display (for example, text, number or telephone). * [`itemProp`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/itemprop): A string. Specifies which property the element represents for structured data crawlers. * [`lang`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang): A string. Specifies the language of the element. @@ -253,7 +253,7 @@ Instead of a ref object (like the one returned by [`useRef`](/reference/react/us When the `<div>` DOM node is added to the screen, React will call your `ref` callback with the DOM `node` as the argument. When that `<div>` DOM node is removed, React will call your `ref` callback with `null`. -React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your component re-renders, the *previous* function will be called with `null` as the argument, and the *next* function will be called with the DOM node. +React will also call your `ref` callback whenever you pass a *different* `ref` callback. In the above example, `(node) => { ... }` is a different function on every render. When your Component re-renders, the *previous* function will be called with `null` as the argument, and the *next* function will be called with the DOM node. #### Parameters {/*ref-callback-parameters*/} diff --git a/src/content/reference/react-dom/components/form.md b/src/content/reference/react-dom/components/form.md index 4b7d5d8a075..b7c91649bfd 100644 --- a/src/content/reference/react-dom/components/form.md +++ b/src/content/reference/react-dom/components/form.md @@ -140,7 +140,7 @@ function AddToCart({productId}) { When `<form>` is rendered by a [Server Component](/reference/react/use-client), and a [Server Action](/reference/react/use-server) is passed to the `<form>`'s `action` prop, the form is [progressively enhanced](https://developer.mozilla.org/en-US/docs/Glossary/Progressive_Enhancement). ### Display a pending state during form submission {/*display-a-pending-state-during-form-submission*/} -To display a pending state when a form is being submitted, you can call the `useFormStatus` Hook in a component rendered in a `<form>` and read the `pending` property returned. +To display a pending state when a form is being submitted, you can call the `useFormStatus` Hook in a Component rendered in a `<form>` and read the `pending` property returned. Here, we use the `pending` property to indicate the form is submitting. diff --git a/src/content/reference/react-dom/components/index.md b/src/content/reference/react-dom/components/index.md index c9b355c8469..36e3a92ab64 100644 --- a/src/content/reference/react-dom/components/index.md +++ b/src/content/reference/react-dom/components/index.md @@ -10,19 +10,19 @@ React supports all of the browser built-in [HTML](https://developer.mozilla.org/ --- -## Common components {/*common-components*/} +## Common Components {/*common-components*/} -All of the built-in browser components support some props and events. +All of the built-in browser Components support some props and events. -* [Common components (e.g. `<div>`)](/reference/react-dom/components/common) +* [Common Components (e.g. `<div>`)](/reference/react-dom/components/common) This includes React-specific props like `ref` and `dangerouslySetInnerHTML`. --- -## Form components {/*form-components*/} +## Form Components {/*form-components*/} -These built-in browser components accept user input: +These built-in browser Components accept user input: * [`<input>`](/reference/react-dom/components/input) * [`<select>`](/reference/react-dom/components/select) @@ -34,7 +34,7 @@ They are special in React because passing the `value` prop to them makes them *[ ## Resource and Metadata Components {/*resource-and-metadata-components*/} -These bulit-in browser components let you load external resources or annotate the document with metadata: +These bulit-in browser Components let you load external resources or annotate the document with metadata: * [`<link>`](/reference/react-dom/components/link) * [`<meta>`](/reference/react-dom/components/meta) @@ -46,7 +46,7 @@ They are special in React because React can render them into the document head, --- -## All HTML components {/*all-html-components*/} +## All HTML Components {/*all-html-components*/} React supports all built-in browser HTML components. This includes: @@ -183,7 +183,7 @@ Experimental versions of React may contain bugs. Don't use them in production. </Note> --- -## All SVG components {/*all-svg-components*/} +## All SVG Components {/*all-svg-components*/} React supports all built-in browser SVG components. This includes: diff --git a/src/content/reference/react-dom/components/input.md b/src/content/reference/react-dom/components/input.md index 706b8ae8ae8..003936d082b 100644 --- a/src/content/reference/react-dom/components/input.md +++ b/src/content/reference/react-dom/components/input.md @@ -364,7 +364,7 @@ function Form() { </button> ``` -The `value` you pass to controlled components should not be `undefined` or `null`. If you need the initial value to be empty (such as with the `firstName` field below), initialize your state variable to an empty string (`''`). +The `value` you pass to controlled Components should not be `undefined` or `null`. If you need the initial value to be empty (such as with the `firstName` field below), initialize your state variable to an empty string (`''`). <Sandpack> @@ -424,7 +424,7 @@ p { font-weight: bold; } ### Optimizing re-rendering on every keystroke {/*optimizing-re-rendering-on-every-keystroke*/} -When you use a controlled input, you set the state on every keystroke. If the component containing your state re-renders a large tree, this can get slow. There's a few ways you can optimize re-rendering performance. +When you use a controlled input, you set the state on every keystroke. If the Component containing your state re-renders a large tree, this can get slow. There's a few ways you can optimize re-rendering performance. For example, suppose you start with a form that re-renders all page content on every keystroke: @@ -587,16 +587,16 @@ function handleChange(e) { } ``` -If this doesn't fix the problem, it's possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you're accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render, for example if the input or one of its parents always receives a different `key` attribute, or if you nest component function definitions (which is not supported and causes the "inner" component to always be considered a different tree). +If this doesn't fix the problem, it's possible that the input gets removed and re-added from the DOM on every keystroke. This can happen if you're accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render, for example if the input or one of its parents always receives a different `key` attribute, or if you nest Component function definitions (which is not supported and causes the "inner" Component to always be considered a different tree). --- -### I'm getting an error: "A component is changing an uncontrolled input to be controlled" {/*im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled*/} +### I'm getting an error: "A Component is changing an uncontrolled input to be controlled" {/*im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled*/} If you provide a `value` to the component, it must remain a string throughout its lifetime. -You cannot pass `value={undefined}` first and later pass `value="some string"` because React won't know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string `value`, not `null` or `undefined`. +You cannot pass `value={undefined}` first and later pass `value="some string"` because React won't know whether you want the Component to be uncontrolled or controlled. A controlled Component should always receive a string `value`, not `null` or `undefined`. If your `value` is coming from an API or a state variable, it might be initialized to `null` or `undefined`. In that case, either set it to an empty string (`''`) initially, or pass `value={someValue ?? ''}` to ensure `value` is a string. diff --git a/src/content/reference/react-dom/components/link.md b/src/content/reference/react-dom/components/link.md index c3331d94c21..128dc98f70e 100644 --- a/src/content/reference/react-dom/components/link.md +++ b/src/content/reference/react-dom/components/link.md @@ -27,7 +27,7 @@ The [built-in browser `<link>` component](https://developer.mozilla.org/en-US/do ### `<link>` {/*link*/} -To link to external resources such as stylesheets, fonts, and icons, or to annotate the document with link metadata, render the [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link). You can render `<link>` from any component and React will [in most cases](#special-rendering-behavior) place the corresponding DOM element in the document head. +To link to external resources such as stylesheets, fonts, and icons, or to annotate the document with link metadata, render the [built-in browser `<link>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link). You can render `<link>` from any Component and React will [in most cases](#special-rendering-behavior) place the corresponding DOM element in the document head. ```js <link rel="icon" href="favicon.ico" /> @@ -79,7 +79,7 @@ Props that are **not recommended** for use with React: #### Special rendering behavior {/*special-rendering-behavior*/} -React will always place the DOM element corresponding to the `<link>` component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<link>` to exist within the DOM, yet it’s convenient and keeps things composable if a component representing a specific page can render `<link>` components itself. +React will always place the DOM element corresponding to the `<link>` Component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<link>` to exist within the DOM, yet it’s convenient and keeps things composable if a Component representing a specific page can render `<link>` Components itself. There are a few exceptions to this: @@ -91,8 +91,8 @@ There are a few exceptions to this: In addition, if the `<link>` is to a stylesheet (namely, it has `rel="stylesheet"` in its props), React treats it specially in the following ways: -* The component that renders `<link>` will [suspend](/reference/react/Suspense) while the stylesheet is loading. -* If multiple components render links to the same stylesheet, React will de-duplicate them and only put a single link into the DOM. Two links are considered the same if they have the same `href` prop. +* The Component that renders `<link>` will [suspend](/reference/react/Suspense) while the stylesheet is loading. +* If multiple Components render links to the same stylesheet, React will de-duplicate them and only put a single link into the DOM. Two links are considered the same if they have the same `href` prop. There are two exception to this special behavior: @@ -102,7 +102,7 @@ There are two exception to this special behavior: This special treatment comes with two caveats: * React will ignore changes to props after the link has been rendered. (React will issue a warning in development if this happens.) -* React may leave the link in the DOM even after the component that rendered it has been unmounted. +* React may leave the link in the DOM even after the Component that rendered it has been unmounted. --- @@ -133,7 +133,7 @@ export default function BlogPage() { ### Linking to a stylesheet {/*linking-to-a-stylesheet*/} -If a component depends on a certain stylesheet in order to be displayed correctly, you can render a link to that stylesheet within the component. Your component will [suspend](/reference/react/Suspense) while the stylesheet is loading. You must supply the `precedence` prop, which tells React where to place this stylesheet relative to others — stylesheets with higher precedence can override those with lower precedence. +If a Component depends on a certain stylesheet in order to be displayed correctly, you can render a link to that stylesheet within the component. Your Component will [suspend](/reference/react/Suspense) while the stylesheet is loading. You must supply the `precedence` prop, which tells React where to place this stylesheet relative to others — stylesheets with higher precedence can override those with lower precedence. <Note> When you want to use a stylesheet, it can be beneficial to call the [preinit](/reference/react-dom/preinit) function. Calling this function may allow the browser to start fetching the stylesheet earlier than if you just render a `<link>` component, for example by sending an [HTTP Early Hints response](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/103). @@ -158,7 +158,7 @@ export default function SiteMapPage() { ### Controlling stylesheet precedence {/*controlling-stylesheet-precedence*/} -Stylesheets can conflict with each other, and when they do, the browser goes with the one that comes later in the document. React lets you control the order of stylesheets with the `precedence` prop. In this example, two components render stylesheets, and the one with the higher precedence goes later in the document even though the component that renders it comes earlier. +Stylesheets can conflict with each other, and when they do, the browser goes with the one that comes later in the document. React lets you control the order of stylesheets with the `precedence` prop. In this example, two Components render stylesheets, and the one with the higher precedence goes later in the document even though the Component that renders it comes earlier. {/*FIXME: this doesn't appear to actually work -- I guess precedence isn't implemented yet?*/} @@ -217,7 +217,7 @@ function Component() { ### Annotating specific items within the document with links {/*annotating-specific-items-within-the-document-with-links*/} -You can use the `<link>` component with the `itemProp` prop to annotate specific items within the document with links to related resources. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component. +You can use the `<link>` Component with the `itemProp` prop to annotate specific items within the document with links to related resources. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component. ```js <section itemScope> diff --git a/src/content/reference/react-dom/components/meta.md b/src/content/reference/react-dom/components/meta.md index 801ca2af16a..81425b752b5 100644 --- a/src/content/reference/react-dom/components/meta.md +++ b/src/content/reference/react-dom/components/meta.md @@ -28,7 +28,7 @@ The [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/do ### `<meta>` {/*meta*/} -To add document metadata, render the [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). You can render `<meta>` from any component and React will always place the corresponding DOM element in the document head. +To add document metadata, render the [built-in browser `<meta>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta). You can render `<meta>` from any Component and React will always place the corresponding DOM element in the document head. ```js <meta name="keywords" content="React, JavaScript, semantic markup, html" /> @@ -40,7 +40,7 @@ To add document metadata, render the [built-in browser `<meta>` component](https `<meta>` supports all [common element props.](/reference/react-dom/components/common#props) -It should have *exactly one* of the following props: `name`, `httpEquiv`, `charset`, `itemProp`. The `<meta>` component does something different depending on which of these props is specified. +It should have *exactly one* of the following props: `name`, `httpEquiv`, `charset`, `itemProp`. The `<meta>` Component does something different depending on which of these props is specified. * `name`: a string. Specifies the [kind of metadata](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name) to be attached to the document. * `charset`: a string. Specifies the character set used by the document. The only valid value is `"utf-8"`. @@ -50,7 +50,7 @@ It should have *exactly one* of the following props: `name`, `httpEquiv`, `chars #### Special rendering behavior {/*special-rendering-behavior*/} -React will always place the DOM element corresponding to the `<meta>` component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<meta>` to exist within the DOM, yet it’s convenient and keeps things composable if a component representing a specific page can render `<meta>` components itself. +React will always place the DOM element corresponding to the `<meta>` Component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<meta>` to exist within the DOM, yet it’s convenient and keeps things composable if a Component representing a specific page can render `<meta>` Components itself. There is one exception to this: if `<meta>` has an [`itemProp`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/itemprop) prop, there is no special behavior, because in this case it doesn’t represent metadata about the document but rather metadata about a specific part of the page. @@ -65,10 +65,10 @@ You can annotate the document with metadata such as keywords, a summary, or the ```html <meta name="author" content="John Smith" /> <meta name="keywords" content="React, JavaScript, semantic markup, html" /> -<meta name="description" content="API reference for the <meta> component in React DOM" /> +<meta name="description" content="API reference for the <meta> Component in React DOM" /> ``` -You can render the `<meta>` component from any component. React will put a `<meta>` DOM node in the document `<head>`. +You can render the `<meta>` Component from any component. React will put a `<meta>` DOM node in the document `<head>`. <SandpackWithHTMLOutput> @@ -91,7 +91,7 @@ export default function SiteMapPage() { ### Annotating specific items within the document with metadata {/*annotating-specific-items-within-the-document-with-metadata*/} -You can use the `<meta>` component with the `itemProp` prop to annotate specific items within the document with metadata. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component. +You can use the `<meta>` Component with the `itemProp` prop to annotate specific items within the document with metadata. In this case, React will *not* place these annotations within the document `<head>` but will place them like any other React component. ```js <section itemScope> diff --git a/src/content/reference/react-dom/components/option.md b/src/content/reference/react-dom/components/option.md index 84725854cdb..07336629917 100644 --- a/src/content/reference/react-dom/components/option.md +++ b/src/content/reference/react-dom/components/option.md @@ -54,7 +54,7 @@ Additionally, `<option>` supports these props: ### Displaying a select box with options {/*displaying-a-select-box-with-options*/} -Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form. +Render a `<select>` with a list of `<option>` Components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form. [Read more about displaying a `<select>` with a list of `<option>` components.](/reference/react-dom/components/select) diff --git a/src/content/reference/react-dom/components/script.md b/src/content/reference/react-dom/components/script.md index fc4b0127725..c0572ea4346 100644 --- a/src/content/reference/react-dom/components/script.md +++ b/src/content/reference/react-dom/components/script.md @@ -27,7 +27,7 @@ The [built-in browser `<script>` component](https://developer.mozilla.org/en-US/ ### `<script>` {/*script*/} -To add inline or external scripts to your document, render the [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script). You can render `<script>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical scripts. +To add inline or external scripts to your document, render the [built-in browser `<script>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script). You can render `<script>` from any Component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical scripts. ```js <script> alert("hi!") </script> @@ -68,7 +68,7 @@ Props that are **not recommended** for use with React: #### Special rendering behavior {/*special-rendering-behavior*/} -React can move `<script>` components to the document's `<head>`, de-duplicate identical scripts, and [suspend](/reference/react/Suspense) while the script is loading. +React can move `<script>` Components to the document's `<head>`, de-duplicate identical scripts, and [suspend](/reference/react/Suspense) while the script is loading. To opt into this behavior, provide the `src` and `async={true}` props. React will de-duplicate scripts if they have the same `src`. The `async` prop must be true to allow scripts to be safely moved. @@ -77,7 +77,7 @@ If you supply any of the `onLoad` or `onError` props, there is no special behavi This special treatment comes with two caveats: * React will ignore changes to props after the script has been rendered. (React will issue a warning in development if this happens.) -* React may leave the script in the DOM even after the component that rendered it has been unmounted. (This has no effect as scripts just execute once when they are inserted into the DOM.) +* React may leave the script in the DOM even after the Component that rendered it has been unmounted. (This has no effect as scripts just execute once when they are inserted into the DOM.) --- @@ -85,9 +85,9 @@ This special treatment comes with two caveats: ### Rendering an external script {/*rendering-an-external-script*/} -If a component depends on certain scripts in order to be displayed correctly, you can render a `<script>` within the component. +If a Component depends on certain scripts in order to be displayed correctly, you can render a `<script>` within the component. -If you supply an `src` and `async` prop, your component will suspend while the script is loading. React will de-duplicate scripts that have the same `src`, inserting only one of them into the DOM even if multiple components render it. +If you supply an `src` and `async` prop, your Component will suspend while the script is loading. React will de-duplicate scripts that have the same `src`, inserting only one of them into the DOM even if multiple Components render it. <SandpackWithHTMLOutput> @@ -120,7 +120,7 @@ When you want to use a script, it can be beneficial to call the [preinit](/refer ### Rendering an inline script {/*rendering-an-inline-script*/} -To include an inline script, render the `<script>` component with the script source code as its children. Inline scripts are not de-duplicated or moved to the document `<head>`, and since they don't load any external resources, they will not cause your component to suspend. +To include an inline script, render the `<script>` Component with the script source code as its children. Inline scripts are not de-duplicated or moved to the document `<head>`, and since they don't load any external resources, they will not cause your Component to suspend. <SandpackWithHTMLOutput> diff --git a/src/content/reference/react-dom/components/select.md b/src/content/reference/react-dom/components/select.md index 0dbdc15375a..4e8c313d3ca 100644 --- a/src/content/reference/react-dom/components/select.md +++ b/src/content/reference/react-dom/components/select.md @@ -52,7 +52,7 @@ These `<select>` props are relevant both for uncontrolled and controlled select * [`autoComplete`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#autocomplete): A string. Specifies one of the possible [autocomplete behaviors.](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values) * [`autoFocus`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#autofocus): A boolean. If `true`, React will focus the element on mount. -* `children`: `<select>` accepts [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option), [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup), and [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) components as children. You can also pass your own components as long as they eventually render one of the allowed components. If you pass your own components that eventually render `<option>` tags, each `<option>` you render must have a `value`. +* `children`: `<select>` accepts [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option), [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup), and [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist) Components as children. You can also pass your own Components as long as they eventually render one of the allowed components. If you pass your own Components that eventually render `<option>` tags, each `<option>` you render must have a `value`. * [`disabled`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#disabled): A boolean. If `true`, the select box will not be interactive and will appear dimmed. * [`form`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#form): A string. Specifies the `id` of the `<form>` this select box belongs to. If omitted, it's the closest parent form. * [`multiple`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#multiple): A boolean. If `true`, the browser allows [multiple selection.](#enabling-multiple-selection) @@ -80,7 +80,7 @@ These `<select>` props are relevant both for uncontrolled and controlled select ### Displaying a select box with options {/*displaying-a-select-box-with-options*/} -Render a `<select>` with a list of `<option>` components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form. +Render a `<select>` with a list of `<option>` Components inside to display a select box. Give each `<option>` a `value` representing the data to be submitted with the form. <Sandpack> diff --git a/src/content/reference/react-dom/components/style.md b/src/content/reference/react-dom/components/style.md index 2c5d7b97b85..3d2c8c80dfc 100644 --- a/src/content/reference/react-dom/components/style.md +++ b/src/content/reference/react-dom/components/style.md @@ -27,7 +27,7 @@ The [built-in browser `<style>` component](https://developer.mozilla.org/en-US/d ### `<style>` {/*style*/} -To add inline styles to your document, render the [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style). You can render `<style>` from any component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical styles. +To add inline styles to your document, render the [built-in browser `<style>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style). You can render `<style>` from any Component and React will [in certain cases](#special-rendering-behavior) place the corresponding DOM element in the document head and de-duplicate identical styles. ```js <style>{` p { color: red; } `}</style> @@ -52,14 +52,14 @@ Props that are **not recommended** for use with React: #### Special rendering behavior {/*special-rendering-behavior*/} -React can move `<style>` components to the document's `<head>`, de-duplicate identical stylesheets, and [suspend](/reference/react/Suspense) while the stylesheet is loading. +React can move `<style>` Components to the document's `<head>`, de-duplicate identical stylesheets, and [suspend](/reference/react/Suspense) while the stylesheet is loading. To opt into this behavior, provide the `href` and `precedence` props. React will de-duplicate styles if they have the same `href`. The precedence prop tells React where to rank the `<style>` DOM node relative to others in the document `<head>`, which determines which stylesheet can override the other. This special treatment comes with two caveats: * React will ignore changes to props after the style has been rendered. (React will issue a warning in development if this happens.) -* React may leave the style in the DOM even after the component that rendered it has been unmounted. +* React may leave the style in the DOM even after the Component that rendered it has been unmounted. --- @@ -67,9 +67,9 @@ This special treatment comes with two caveats: ### Rendering an inline CSS stylesheet {/*rendering-an-inline-css-stylesheet*/} -If a component depends on certain CSS styles in order to be displayed correctly, you can render an inline stylesheet within the component. +If a Component depends on certain CSS styles in order to be displayed correctly, you can render an inline stylesheet within the component. -If you supply an `href` and `precedence` prop, your component will suspend while the stylesheet is loading. (Even with inline stylesheets, there may be a loading time due to fonts and images that the stylesheet refers to.) The `href` prop should uniquely identify the stylesheet, because React will de-duplicate stylesheets that have the same `href`. +If you supply an `href` and `precedence` prop, your Component will suspend while the stylesheet is loading. (Even with inline stylesheets, there may be a loading time due to fonts and images that the stylesheet refers to.) The `href` prop should uniquely identify the stylesheet, because React will de-duplicate stylesheets that have the same `href`. <SandpackWithHTMLOutput> diff --git a/src/content/reference/react-dom/components/textarea.md b/src/content/reference/react-dom/components/textarea.md index b1ef71474d4..1e9c9bb3de9 100644 --- a/src/content/reference/react-dom/components/textarea.md +++ b/src/content/reference/react-dom/components/textarea.md @@ -409,15 +409,15 @@ function handleChange(e) { } ``` -If this doesn't fix the problem, it's possible that the text area gets removed and re-added from the DOM on every keystroke. This can happen if you're accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render. For example, this can happen if the text area or one of its parents always receives a different `key` attribute, or if you nest component definitions (which is not allowed in React and causes the "inner" component to remount on every render). +If this doesn't fix the problem, it's possible that the text area gets removed and re-added from the DOM on every keystroke. This can happen if you're accidentally [resetting state](/learn/preserving-and-resetting-state) on every re-render. For example, this can happen if the text area or one of its parents always receives a different `key` attribute, or if you nest Component definitions (which is not allowed in React and causes the "inner" Component to remount on every render). --- -### I'm getting an error: "A component is changing an uncontrolled input to be controlled" {/*im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled*/} +### I'm getting an error: "A Component is changing an uncontrolled input to be controlled" {/*im-getting-an-error-a-component-is-changing-an-uncontrolled-input-to-be-controlled*/} If you provide a `value` to the component, it must remain a string throughout its lifetime. -You cannot pass `value={undefined}` first and later pass `value="some string"` because React won't know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string `value`, not `null` or `undefined`. +You cannot pass `value={undefined}` first and later pass `value="some string"` because React won't know whether you want the Component to be uncontrolled or controlled. A controlled Component should always receive a string `value`, not `null` or `undefined`. If your `value` is coming from an API or a state variable, it might be initialized to `null` or `undefined`. In that case, either set it to an empty string (`''`) initially, or pass `value={someValue ?? ''}` to ensure `value` is a string. diff --git a/src/content/reference/react-dom/components/title.md b/src/content/reference/react-dom/components/title.md index 24b2aba2f07..3470a1de4bb 100644 --- a/src/content/reference/react-dom/components/title.md +++ b/src/content/reference/react-dom/components/title.md @@ -28,7 +28,7 @@ The [built-in browser `<title>` component](https://developer.mozilla.org/en-US/d ### `<title>` {/*title*/} -To specify the title of the document, render the [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). You can render `<title>` from any component and React will always place the corresponding DOM element in the document head. +To specify the title of the document, render the [built-in browser `<title>` component](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title). You can render `<title>` from any Component and React will always place the corresponding DOM element in the document head. ```js <title>My Blog @@ -40,11 +40,11 @@ To specify the title of the document, render the [built-in browser `` com `<title>` supports all [common element props.](/reference/react-dom/components/common#props) -* `children`: `<title>` accepts only text as a child. This text will become the title of the document. You can also pass your own components as long as they only render text. +* `children`: `<title>` accepts only text as a child. This text will become the title of the document. You can also pass your own Components as long as they only render text. #### Special rendering behavior {/*special-rendering-behavior*/} -React will always place the DOM element corresponding to the `<title>` component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<title>` to exist within the DOM, yet it’s convenient and keeps things composable if a component representing a specific page can render its `<title>` itself. +React will always place the DOM element corresponding to the `<title>` Component within the document’s `<head>`, regardless of where in the React tree it is rendered. The `<head>` is the only valid place for `<title>` to exist within the DOM, yet it’s convenient and keeps things composable if a Component representing a specific page can render its `<title>` itself. There are two exception to this: * If `<title>` is within an `<svg>` component, then there is no special behavior, because in this context it doesn’t represent the document’s title but rather is an [accessibility annotation for that SVG graphic](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title). @@ -52,7 +52,7 @@ There are two exception to this: <Pitfall> -Only render a single `<title>` at a time. If more than one component renders a `<title>` tag at the same time, React will place all of those titles in the document head. When this happens, the behavior of browsers and search engines is undefined. +Only render a single `<title>` at a time. If more than one Component renders a `<title>` tag at the same time, React will place all of those titles in the document head. When this happens, the behavior of browsers and search engines is undefined. </Pitfall> @@ -62,7 +62,7 @@ Only render a single `<title>` at a time. If more than one component renders a ` ### Set the document title {/*set-the-document-title*/} -Render the `<title>` component from any component with text as its children. React will put a `<title>` DOM node in the document `<head>`. +Render the `<title>` Component from any Component with text as its children. React will put a `<title>` DOM node in the document `<head>`. <SandpackWithHTMLOutput> @@ -84,13 +84,13 @@ export default function ContactUsPage() { ### Use variables in the title {/*use-variables-in-the-title*/} -The children of the `<title>` component must be a single string of text. (Or a single number or a single object with a `toString` method.) It might not be obvious, but using JSX curly braces like this: +The children of the `<title>` Component must be a single string of text. (Or a single number or a single object with a `toString` method.) It might not be obvious, but using JSX curly braces like this: ```js <title>Results page {pageNumber} // 🔴 Problem: This is not a single string ``` -... actually causes the `` component to get a two-element array as its children (the string `"Results page"` and the value of `pageNumber`). This will cause an error. Instead, use string interpolation to pass `<title>` a single string: +... actually causes the `<title>` Component to get a two-element array as its children (the string `"Results page"` and the value of `pageNumber`). This will cause an error. Instead, use string interpolation to pass `<title>` a single string: ```js <title>{`Results page ${pageNumber}`} diff --git a/src/content/reference/react-dom/createPortal.md b/src/content/reference/react-dom/createPortal.md index 0107c20d3e1..9514a4fbfd8 100644 --- a/src/content/reference/react-dom/createPortal.md +++ b/src/content/reference/react-dom/createPortal.md @@ -42,7 +42,7 @@ import { createPortal } from 'react-dom'; [See more examples below.](#usage) -A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React component that renders it. For example, the child can access the context provided by the parent tree, and events bubble up from children to parents according to the React tree. +A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React Component that renders it. For example, the child can access the context provided by the parent tree, and events bubble up from children to parents according to the React tree. #### Parameters {/*parameters*/} @@ -66,7 +66,7 @@ A portal only changes the physical placement of the DOM node. In every other way ### Rendering to a different part of the DOM {/*rendering-to-a-different-part-of-the-dom*/} -*Portals* let your components render some of their children into a different place in the DOM. This lets a part of your component "escape" from whatever containers it may be in. For example, a component can display a modal dialog or a tooltip that appears above and outside of the rest of the page. +*Portals* let your Components render some of their children into a different place in the DOM. This lets a part of your Component "escape" from whatever containers it may be in. For example, a Component can display a modal dialog or a tooltip that appears above and outside of the rest of the page. To create a portal, render the result of `createPortal` with some JSX and the DOM node where it should go: @@ -125,13 +125,13 @@ Notice how the second paragraph visually appears outside the parent `
` with ``` -A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React component that renders it. For example, the child can access the context provided by the parent tree, and events still bubble up from children to parents according to the React tree. +A portal only changes the physical placement of the DOM node. In every other way, the JSX you render into a portal acts as a child node of the React Component that renders it. For example, the child can access the context provided by the parent tree, and events still bubble up from children to parents according to the React tree. --- ### Rendering a modal dialog with a portal {/*rendering-a-modal-dialog-with-a-portal*/} -You can use a portal to create a modal dialog that floats above the rest of the page, even if the component that summons the dialog is inside a container with `overflow: hidden` or other styles that interfere with the dialog. +You can use a portal to create a modal dialog that floats above the rest of the page, even if the Component that summons the dialog is inside a container with `overflow: hidden` or other styles that interfere with the dialog. In this example, the two containers have styles that disrupt the modal dialog, but the one rendered into a portal is unaffected because, in the DOM, the modal is not contained within the parent JSX elements. @@ -246,7 +246,7 @@ Follow the [WAI-ARIA Modal Authoring Practices](https://www.w3.org/WAI/ARIA/apg/ --- -### Rendering React components into non-React server markup {/*rendering-react-components-into-non-react-server-markup*/} +### Rendering React Components into non-React server markup {/*rendering-react-components-into-non-react-server-markup*/} Portals can be useful if your React root is only part of a static or server-rendered page that isn't built with React. For example, if your page is built with a server framework like Rails, you can create areas of interactivity within static areas such as sidebars. Compared with having [multiple separate React roots,](/reference/react-dom/client/createRoot#rendering-a-page-partially-built-with-react) portals let you treat the app as a single React tree with shared state even though its parts render to different parts of the DOM. @@ -342,7 +342,7 @@ p { --- -### Rendering React components into non-React DOM nodes {/*rendering-react-components-into-non-react-dom-nodes*/} +### Rendering React Components into non-React DOM nodes {/*rendering-react-components-into-non-react-dom-nodes*/} You can also use a portal to manage the content of a DOM node that's managed outside of React. For example, suppose you're integrating with a non-React map widget and you want to render React content inside a popup. To do this, declare a `popupContainer` state variable to store the DOM node you're going to render into: diff --git a/src/content/reference/react-dom/findDOMNode.md b/src/content/reference/react-dom/findDOMNode.md index 8e7b0065397..559d867c26a 100644 --- a/src/content/reference/react-dom/findDOMNode.md +++ b/src/content/reference/react-dom/findDOMNode.md @@ -43,23 +43,23 @@ const domNode = findDOMNode(componentInstance); #### Returns {/*returns*/} -`findDOMNode` returns the first closest browser DOM node within the given `componentInstance`. When a component renders to `null`, or renders `false`, `findDOMNode` returns `null`. When a component renders to a string, `findDOMNode` returns a text DOM node containing that value. +`findDOMNode` returns the first closest browser DOM node within the given `componentInstance`. When a Component renders to `null`, or renders `false`, `findDOMNode` returns `null`. When a Component renders to a string, `findDOMNode` returns a text DOM node containing that value. #### Caveats {/*caveats*/} -* A component may return an array or a [Fragment](/reference/react/Fragment) with multiple children. In that case `findDOMNode`, will return the DOM node corresponding to the first non-empty child. +* A Component may return an array or a [Fragment](/reference/react/Fragment) with multiple children. In that case `findDOMNode`, will return the DOM node corresponding to the first non-empty child. -* `findDOMNode` only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a component that has yet to be created), an exception will be thrown. +* `findDOMNode` only works on mounted Components (that is, Components that have been placed in the DOM). If you try to call this on a Component that has not been mounted yet (like calling `findDOMNode()` in `render()` on a Component that has yet to be created), an exception will be thrown. -* `findDOMNode` only returns the result at the time of your call. If a child component renders a different node later, there is no way for you to be notified of this change. +* `findDOMNode` only returns the result at the time of your call. If a child Component renders a different node later, there is no way for you to be notified of this change. -* `findDOMNode` accepts a class component instance, so it can't be used with function components. +* `findDOMNode` accepts a class Component instance, so it can't be used with function components. --- ## Usage {/*usage*/} -### Finding the root DOM node of a class component {/*finding-the-root-dom-node-of-a-class-component*/} +### Finding the root DOM node of a class Component {/*finding-the-root-dom-node-of-a-class-component*/} Call `findDOMNode` with a [class component](/reference/react/Component) instance (usually, `this`) to find the DOM node it has rendered. @@ -257,7 +257,7 @@ export default function AutoselectingInput() { ### Reading a child component's DOM node from a forwarded ref {/*reading-a-child-components-dom-node-from-a-forwarded-ref*/} -In this example, `findDOMNode(this)` finds a DOM node that belongs to another component. The `AutoselectingInput` renders `MyInput`, which is your own component that renders a browser ``. +In this example, `findDOMNode(this)` finds a DOM node that belongs to another component. The `AutoselectingInput` renders `MyInput`, which is your own Component that renders a browser ``. @@ -307,7 +307,7 @@ export default function MyInput() { Notice that calling `findDOMNode(this)` inside `AutoselectingInput` still gives you the DOM ``--even though the JSX for this `` is hidden inside the `MyInput` component. This seems convenient for the above example, but it leads to fragile code. Imagine that you wanted to edit `MyInput` later and add a wrapper `
` around it. This would break the code of `AutoselectingInput` (which expects to find an ``). -To replace `findDOMNode` in this example, the two components need to coordinate: +To replace `findDOMNode` in this example, the two Components need to coordinate: 1. `AutoSelectingInput` should declare a ref, like [in the earlier example](#reading-components-own-dom-node-from-a-ref), and pass it to ``. 2. `MyInput` should be declared with [`forwardRef`](/reference/react/forwardRef) to take that ref and forward it down to the `` node. @@ -368,7 +368,7 @@ export default MyInput; -Here is how this code would look like with function components instead of classes: +Here is how this code would look like with function Components instead of classes: @@ -422,7 +422,7 @@ export default MyInput; ### Adding a wrapper `
` element {/*adding-a-wrapper-div-element*/} -Sometimes a component needs to know the position and size of its children. This makes it tempting to find the children with `findDOMNode(this)`, and then use DOM methods like [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) for measurements. +Sometimes a Component needs to know the position and size of its children. This makes it tempting to find the children with `findDOMNode(this)`, and then use DOM methods like [`getBoundingClientRect`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) for measurements. There is currently no direct equivalent for this use case, which is why `findDOMNode` is deprecated but is not yet removed completely from React. In the meantime, you can try rendering a wrapper `
` node around the content as a workaround, and getting a ref to that node. However, extra wrappers can break styling. diff --git a/src/content/reference/react-dom/hooks/useFormState.md b/src/content/reference/react-dom/hooks/useFormState.md index e2a8d539402..f58d8eaf215 100644 --- a/src/content/reference/react-dom/hooks/useFormState.md +++ b/src/content/reference/react-dom/hooks/useFormState.md @@ -29,7 +29,7 @@ const [state, formAction] = useFormState(fn, initialState, permalink?); {/* TODO T164397693: link to actions documentation once it exists */} -Call `useFormState` at the top level of your component to create component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useFormState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided. +Call `useFormState` at the top level of your Component to create Component state that is updated [when a form action is invoked](/reference/react-dom/components/form). You pass `useFormState` an existing form action function as well as an initial state, and it returns a new action that you use in your form, along with the latest form state. The latest form state is also passed to the function that you provided. ```js import { useFormState } from "react-dom"; @@ -59,7 +59,7 @@ If used with a Server Action, `useFormState` allows the server's response from s * `fn`: The function to be called when the form is submitted or button pressed. When the function is called, it will receive the previous state of the form (initially the `initialState` that you pass, subsequently its previous return value) as its initial argument, followed by the arguments that a form action normally receives. * `initialState`: The value you want the state to be initially. It can be any serializable value. This argument is ignored after the action is first invoked. -* **optional** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server action](/reference/react/use-server) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page's URL. Ensure that the same form component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect. +* **optional** `permalink`: A string containing the unique page URL that this form modifies. For use on pages with dynamic content (eg: feeds) in conjunction with progressive enhancement: if `fn` is a [server action](/reference/react/use-server) and the form is submitted before the JavaScript bundle loads, the browser will navigate to the specified permalink URL, rather than the current page's URL. Ensure that the same form Component is rendered on the destination page (including the same action `fn` and `permalink`) so that React knows how to pass the state through. Once the form has been hydrated, this parameter has no effect. {/* TODO T164397693: link to serializable values docs once it exists */} @@ -68,11 +68,11 @@ If used with a Server Action, `useFormState` allows the server's response from s `useFormState` returns an array with exactly two values: 1. The current state. During the first render, it will match the `initialState` you have passed. After the action is invoked, it will match the value returned by the action. -2. A new action that you can pass as the `action` prop to your `form` component or `formAction` prop to any `button` component within the form. +2. A new action that you can pass as the `action` prop to your `form` Component or `formAction` prop to any `button` Component within the form. #### Caveats {/*caveats*/} -* When used with a framework that supports React Server Components, `useFormState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, it is equivalent to component local state. +* When used with a framework that supports React Server Components, `useFormState` lets you make forms interactive before JavaScript has executed on the client. When used without Server Components, it is equivalent to Component local state. * The function passed to `useFormState` receives an extra argument, the previous or initial state, as its first argument. This makes its signature different than if it were used directly as a form action without using `useFormState`. --- @@ -81,7 +81,7 @@ If used with a Server Action, `useFormState` allows the server's response from s ### Using information returned by a form action {/*using-information-returned-by-a-form-action*/} -Call `useFormState` at the top level of your component to access the return value of an action from the last time a form was submitted. +Call `useFormState` at the top level of your Component to access the return value of an action from the last time a form was submitted. ```js [[1, 5, "state"], [2, 5, "formAction"], [3, 5, "action"], [4, 5, "null"], [2, 8, "formAction"]] import { useFormState } from 'react-dom'; diff --git a/src/content/reference/react-dom/hooks/useFormStatus.md b/src/content/reference/react-dom/hooks/useFormStatus.md index 70feceaeafc..437ff2dc864 100644 --- a/src/content/reference/react-dom/hooks/useFormStatus.md +++ b/src/content/reference/react-dom/hooks/useFormStatus.md @@ -47,7 +47,7 @@ export default function App() { } ``` -To get status information, the `Submit` component must be rendered within a `
`. The Hook returns information like the `pending` property which tells you if the form is actively submitting. +To get status information, the `Submit` Component must be rendered within a ``. The Hook returns information like the `pending` property which tells you if the form is actively submitting. In the above example, `Submit` uses this information to disable `