Browse Source

[Beta] Add link anchor for ExpandableExample (Deep Dive) (#5310)

* [Beta] add link anchor for expandable example

* [Beta] Rewrite Suspense API, add useDeferredValue API (#5308)

* [Beta] Rewrite Suspense API

* edits

* more udv

* edits

* edit

* more ref

* extract

* Temporary remove use

* [Beta] deep dive title reuse existing mechanism

* [Beta] adjust deep dive MDX format

* [Beta] fix deep dive MDX format mismatch

* [Beta] optional chain the condition for ReactNode

* Update the link to the Node.js stream module (#5298)

Fix #5297.

* [Beta] Add deps to useEffect example

* [Beta] throw error if no title found in deepdive

* [Beta] fix throw error in tsx

* Update acdlite picture (#5313)

I kinda like this one more

* [Beta] add link anchor for expandable example

* [Beta] deep dive title reuse existing mechanism

* [Beta] adjust deep dive MDX format

* [Beta] fix deep dive MDX format mismatch

* [Beta] optional chain the condition for ReactNode

* [Beta] throw error if no title found in deepdive

* [Beta] fix throw error in tsx

* [Beta] adjust deep dive MDX format

Co-authored-by: Jiawei.Jing <jiawei.jing@ambergroup.co.jp>
Co-authored-by: dan <dan.abramov@gmail.com>
Co-authored-by: Fuqiao Xue <xfq@w3.org>
Co-authored-by: Andrew Clark <git@andrewclark.io>
main
Jing Jiawei 2 years ago
committed by GitHub
parent
commit
cb9854a549
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      beta/src/components/MDX/ExpandableExample.tsx
  2. 4
      beta/src/content/apis/react/Children.md
  3. 4
      beta/src/content/apis/react/Fragment.md
  4. 4
      beta/src/content/apis/react/createElement.md
  5. 4
      beta/src/content/apis/react/isValidElement.md
  6. 4
      beta/src/content/apis/react/memo.md
  7. 8
      beta/src/content/apis/react/useCallback.md
  8. 8
      beta/src/content/apis/react/useDeferredValue.md
  9. 4
      beta/src/content/apis/react/useEffect.md
  10. 4
      beta/src/content/apis/react/useId.md
  11. 12
      beta/src/content/apis/react/useMemo.md
  12. 4
      beta/src/content/apis/react/useRef.md
  13. 4
      beta/src/content/apis/react/useState.md
  14. 4
      beta/src/content/learn/add-react-to-a-website.md
  15. 8
      beta/src/content/learn/choosing-the-state-structure.md
  16. 6
      beta/src/content/learn/conditional-rendering.md
  17. 4
      beta/src/content/learn/extracting-state-logic-into-a-reducer.md
  18. 6
      beta/src/content/learn/importing-and-exporting-components.md
  19. 8
      beta/src/content/learn/keeping-components-pure.md
  20. 4
      beta/src/content/learn/lifecycle-of-reactive-effects.md
  21. 14
      beta/src/content/learn/manipulating-the-dom-with-refs.md
  22. 4
      beta/src/content/learn/preserving-and-resetting-state.md
  23. 8
      beta/src/content/learn/reacting-to-input-with-state.md
  24. 4
      beta/src/content/learn/referencing-values-with-refs.md
  25. 4
      beta/src/content/learn/removing-effect-dependencies.md
  26. 4
      beta/src/content/learn/render-and-commit.md
  27. 4
      beta/src/content/learn/rendering-lists.md
  28. 4
      beta/src/content/learn/responding-to-events.md
  29. 12
      beta/src/content/learn/reusing-logic-with-custom-hooks.md
  30. 4
      beta/src/content/learn/separating-events-from-effects.md
  31. 4
      beta/src/content/learn/sharing-state-between-components.md
  32. 4
      beta/src/content/learn/state-a-components-memory.md
  33. 12
      beta/src/content/learn/synchronizing-with-effects.md
  34. 4
      beta/src/content/learn/thinking-in-react.md
  35. 20
      beta/src/content/learn/updating-objects-in-state.md
  36. 4
      beta/src/content/learn/writing-markup-with-jsx.md
  37. 4
      beta/src/content/learn/you-might-not-need-an-effect.md
  38. 6
      beta/src/content/learn/your-first-component.md

32
beta/src/components/MDX/ExpandableExample.tsx

@ -8,24 +8,25 @@ import {IconChevron} from '../Icon/IconChevron';
import {IconDeepDive} from '../Icon/IconDeepDive';
import {IconCodeBlock} from '../Icon/IconCodeBlock';
import {Button} from '../Button';
import {H4} from './Heading';
interface ExpandableExampleProps {
children: React.ReactNode;
title: string;
excerpt?: string;
type: 'DeepDive' | 'Example';
}
function ExpandableExample({
children,
title,
excerpt,
type,
}: ExpandableExampleProps) {
function ExpandableExample({children, excerpt, type}: ExpandableExampleProps) {
const [isExpanded, setIsExpanded] = React.useState(false);
const isDeepDive = type === 'DeepDive';
const isExample = type === 'Example';
if (!Array.isArray(children) || children[0].type.mdxName !== 'h4') {
throw Error(
`Expandable content ${type} is missing a corresponding title at the beginning`
);
}
return (
<details
open={isExpanded}
@ -40,8 +41,11 @@ function ExpandableExample({
className="list-none p-8"
tabIndex={-1 /* there's a button instead */}
onClick={(e) => {
// We toggle using a button instead of this whole area.
e.preventDefault();
// We toggle using a button instead of this whole area,
// with an escape case for the header anchor link
if (!(e.target instanceof SVGElement)) {
e.preventDefault();
}
}}>
<h5
className={cn('mb-4 uppercase font-bold flex items-center text-sm', {
@ -62,9 +66,11 @@ function ExpandableExample({
)}
</h5>
<div className="mb-4">
<h3 className="text-xl font-bold text-primary dark:text-primary-dark">
{title}
</h3>
<H4
id={children[0].props.id}
className="text-xl font-bold text-primary dark:text-primary-dark">
{children[0].props.children}
</H4>
{excerpt && <div>{excerpt}</div>}
</div>
<Button
@ -87,7 +93,7 @@ function ExpandableExample({
'dark:border-purple-60 border-purple-10 ': isDeepDive,
'dark:border-yellow-60 border-yellow-50': isExample,
})}>
{children}
{children.slice(1)}
</div>
</details>
);

4
beta/src/content/apis/react/Children.md

@ -126,7 +126,9 @@ export default function RowList({ children }) {
</Sandpack>
<DeepDive title="Why is the children prop not always an array?">
<DeepDive>
#### Why is the children prop not always an array? {/*why-is-the-children-prop-not-always-an-array*/}
In React, the `children` prop is considered an *opaque* data structure. This means that you shouldn't rely on how it is structured. To transform, filter, or count children, you should use the `Children` methods.

4
beta/src/content/apis/react/Fragment.md

@ -74,7 +74,9 @@ function PostBody({ body }) {
</Sandpack>
<DeepDive title="How to write a Fragment without the special syntax?">
<DeepDive>
#### How to write a Fragment without the special syntax? {/*how-to-write-a-fragment-without-the-special-syntax*/}
The example above is equivalent to importing `Fragment` from React:

4
beta/src/content/apis/react/createElement.md

@ -129,7 +129,9 @@ export default function App() {
Both coding styles are fine, so you can use whichever one you prefer for your project. The main benefit of using JSX compared to `createElement` is that it's easy to see which closing tag corresponds to which opening tag.
<DeepDive title="What is a React element, exactly?">
<DeepDive>
#### What is a React element, exactly? {/*what-is-a-react-element-exactly*/}
An element is a lightweight description of a piece of the user interface. For example, both `<Greeting name="Taylor" />` and `createElement(Greeting, { name: 'Taylor' })` produce an object like this:

4
beta/src/content/apis/react/isValidElement.md

@ -59,7 +59,9 @@ It is very uncommon to need `isValidElement`. It's mostly useful if you're calli
Unless you have some very specific reason to add an `isValidElement` check, you probably don't need it.
<DeepDive title="React elements vs React nodes">
<DeepDive>
#### React elements vs React nodes {/*react-elements-vs-react-nodes*/}
When you write a component, you can return any kind of *React node* from it:

4
beta/src/content/apis/react/memo.md

@ -80,7 +80,9 @@ label {
</Note>
<DeepDive title="Should you add memo everywhere?">
<DeepDive>
#### Should you add memo everywhere? {/*should-you-add-memo-everywhere*/}
If your app is like this site, and most interactions are coarse (like replacing a page or an entire section), memoization is usually unnecessary. On the other hand, if your app is more like a drawing editor, and most interactions are granular (like moving shapes), then you might find memoization very helpful.

8
beta/src/content/apis/react/useCallback.md

@ -124,7 +124,9 @@ function ProductPage({ productId, referrer, theme }) {
</Note>
<DeepDive title="How is useCallback related to useMemo?">
<DeepDive>
#### How is useCallback related to useMemo? {/*how-is-usecallback-related-to-usememo*/}
You will often see [`useMemo`](/apis/react/useMemo) alongside `useCallback`. They are both useful when you're trying to optimize a child component. They let you [memoize](https://en.wikipedia.org/wiki/Memoization) (or, in other words, cache) something you're passing down:
@ -171,7 +173,9 @@ function useCallback(fn, dependencies) {
</DeepDive>
<DeepDive title="Should you add useCallback everywhere?">
<DeepDive>
#### Should you add useCallback everywhere? {/*should-you-add-usecallback-everywhere*/}
If your app is like this site, and most interactions are coarse (like replacing a page or an entire section), memoization is usually unnecessary. On the other hand, if your app is more like a drawing editor, and most interactions are granular (like moving shapes), then you might find memoization very helpful.

8
beta/src/content/apis/react/useDeferredValue.md

@ -457,7 +457,9 @@ input { margin: 10px; }
</Sandpack>
<DeepDive title="How does deferring a value work under the hood?">
<DeepDive>
#### How does deferring a value work under the hood? {/*how-does-deferring-a-value-work-under-the-hood*/}
You can think of it as happening in two steps:
@ -894,7 +896,9 @@ This optimization requires `SlowList` to be wrapped in [`memo`.](/apis/react/mem
</Pitfall>
<DeepDive title="How is deferring a value different from debouncing and throttling?">
<DeepDive>
#### How is deferring a value different from debouncing and throttling? {/*how-is-deferring-a-value-different-from-debouncing-and-throttling*/}
There are two common optimization techniques you might have used before in this scenario:

4
beta/src/content/apis/react/useEffect.md

@ -979,7 +979,9 @@ export async function fetchBio(person) {
Writing data fetching directly in Effects gets repetitive and makes it difficult to add optimizations like caching and server rendering later. [It's easier to use a custom Hook--either your own or maintained by the community.](/learn/reusing-logic-with-custom-hooks#when-to-use-custom-hooks)
<DeepDive title="What are good alternatives to data fetching in Effects?">
<DeepDive>
#### What are good alternatives to data fetching in Effects? {/*what-are-good-alternatives-to-data-fetching-in-effects*/}
Writing `fetch` calls inside Effects is a [popular way to fetch data](https://www.robinwieruch.de/react-hooks-fetch-data/), especially in fully client-side apps. This is, however, a very manual approach and it has significant downsides:

4
beta/src/content/apis/react/useId.md

@ -139,7 +139,9 @@ input { margin: 5px; }
</Pitfall>
<DeepDive title="Why is useId better than an incrementing counter?">
<DeepDive>
#### Why is useId better than an incrementing counter? {/*why-is-useid-better-than-an-incrementing-counter*/}
You might be wondering why `useId` is better than incrementing a global variable like `nextId++`.

12
beta/src/content/apis/react/useMemo.md

@ -61,7 +61,9 @@ Usually, this isn't a problem because most calculations are very fast. However,
</Note>
<DeepDive title="How to tell if a calculation is expensive?">
<DeepDive>
#### How to tell if a calculation is expensive? {/*how-to-tell-if-a-calculation-is-expensive*/}
In general, unless you're creating or looping over thousands of objects, it's probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:
@ -89,7 +91,9 @@ Also note that measuring performance in development will not give you the most a
</DeepDive>
<DeepDive title="Should you add useMemo everywhere?">
<DeepDive>
#### Should you add useMemo everywhere? {/*should-you-add-usememo-everywhere*/}
If your app is like this site, and most interactions are coarse (like replacing a page or an entire section), memoization is usually unnecessary. On the other hand, if your app is more like a drawing editor, and most interactions are granular (like moving shapes), then you might find memoization very helpful.
@ -559,7 +563,9 @@ export default function TodoList({ todos, tab, theme }) {
**By wrapping the `visibleTodos` calculation in `useMemo`, you ensure that it has the *same* value between the re-renders** (until dependencies change). You don't *have to* wrap a calculation in `useMemo` unless you do it for some specific reason. In this example, the reason is that you pass it to a component wrapped in [`memo`,](/apis/react/memo) and this lets it skip re-rendering. There are a few other reasons to add `useMemo` which are described further on this page.
<DeepDive title="Memoizing individual JSX nodes">
<DeepDive>
#### Memoizing individual JSX nodes {/*memoizing-individual-jsx-nodes*/}
Instead of wrapping `List` in [`memo`](/apis/react/memo), you could wrap the `<List />` JSX node itself in `useMemo`:

4
beta/src/content/apis/react/useRef.md

@ -472,7 +472,9 @@ function Video() {
Normally, writing or reading `ref.current` during render is not allowed. However, it's fine in this case because the result is always the same, and the condition only executes during initialization so it's fully predictable.
<DeepDive title="How to avoid null checks when initializing useRef later">
<DeepDive>
#### How to avoid null checks when initializing useRef later {/*how-to-avoid-null-checks-when-initializing-use-ref-later*/}
If you use a type checker and don't want to always check for `null`, you can try a pattern like this instead:

4
beta/src/content/apis/react/useState.md

@ -239,7 +239,9 @@ By convention, it's common to name the pending state argument for the first lett
React may [call your updaters twice](#my-initializer-or-updater-function-runs-twice) in development to verify that they are [pure.](/learn/keeping-components-pure)
<DeepDive title="Is using an updater always preferred?">
<DeepDive>
#### Is using an updater always preferred? {/*is-using-an-updater-always-preferred*/}
You might hear a recommendation to always write code like `setAge(a => a + 1)` if the state you're setting is calculated from the previous state. There is no harm in it, but it is also not always necessary.

4
beta/src/content/learn/add-react-to-a-website.md

@ -222,7 +222,9 @@ The tool you just used is called Babel, and you can learn more about it from [it
If you're getting comfortable with build tools and want them to do more for you, [we cover some of the most popular and approachable toolchains here.](/learn/start-a-new-react-project)
<DeepDive title="React without JSX">
<DeepDive>
#### React without JSX {/*react-without-jsx*/}
Originally JSX was introduced to make writing components with React feel as familiar as writing HTML. Since then, the syntax has become widespread. However, there may be instances where you do not want to use or cannot use JSX. You have two options:

8
beta/src/content/learn/choosing-the-state-structure.md

@ -342,7 +342,9 @@ const fullName = firstName + ' ' + lastName;
As a result, the change handlers don't need to do anything special to update it. When you call `setFirstName` or `setLastName`, you trigger a re-render, and then the next `fullName` will be calculated from the fresh data.
<DeepDive title="Don't mirror props in state">
<DeepDive>
#### Don't mirror props in state {/*don-t-mirror-props-in-state*/}
A common example of redundant state is code like this:
@ -1474,7 +1476,9 @@ button { margin: 10px; }
You can nest state as much as you like, but making it "flat" can solve numerous problems. It makes state easier to update, and it helps ensure you don't have duplication in different parts of a nested object.
<DeepDive title="Improving memory usage">
<DeepDive>
#### Improving memory usage {/*improving-memory-usage*/}
Ideally, you would also remove the deleted items (and their children!) from the "table" object to improve memory usage. This version does that. It also [uses Immer](/learn/updating-objects-in-state#write-concise-update-logic-with-immer) to make the update logic more concise.

6
beta/src/content/learn/conditional-rendering.md

@ -204,7 +204,9 @@ return (
You can read it as *"if `isPacked` is true, then (`?`) render `name + ' ✔'`, otherwise (`:`) render `name`"*.
<DeepDive title="Are these two examples fully equivalent?">
<DeepDive>
#### Are these two examples fully equivalent? {/*are-these-two-examples-fully-equivalent*/}
If you're coming from an object-oriented programming background, you might assume that the two examples above are subtly different because one of them may create two different "instances" of `<li>`. But JSX elements aren't "instances" because they don't hold any internal state and aren't real DOM nodes. They're lightweight descriptions, like blueprints. So these two examples, in fact, *are* completely equivalent. [Preserving and Resetting State](/learn/preserving-and-resetting-state) goes into detail about how this works.
@ -761,4 +763,4 @@ export default function DrinkList() {
</Solution>
</Challenges>
</Challenges>

4
beta/src/content/learn/extracting-state-logic-into-a-reducer.md

@ -377,7 +377,9 @@ If you're not yet comfortable with switch statements, using if/else is completel
</Note>
<DeepDive title="Why are reducers called this way?">
<DeepDive>
#### Why are reducers called this way? {/*why-are-reducers-called-this-way*/}
Although reducers can "reduce" the amount of code inside your component, they are actually named after the [`reduce()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) operation that you can perform on arrays.

6
beta/src/content/learn/importing-and-exporting-components.md

@ -126,7 +126,9 @@ Either `'./Gallery.js'` or `'./Gallery'` will work with React, though the former
</Note>
<DeepDive title="Default vs named exports">
<DeepDive>
#### Default vs named exports {/*default-vs-named-exports*/}
There are two primary ways to export values with JavaScript: default exports and named exports. So far, our examples have only used default exports. But you can use one or both of them in the same file. **A file can have no more than one _default_ export, but it can have as many _named_ exports as you like.**
@ -413,4 +415,4 @@ img { margin: 0 10px 10px 0; height: 90px; }
</Solution>
</Challenges>
</Challenges>

8
beta/src/content/learn/keeping-components-pure.md

@ -145,7 +145,9 @@ Now your component is pure, as the JSX it returns only depends on the `guest` pr
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 title="Detecting impure calculations with StrictMode">
<DeepDive>
#### Detecting impure calculations with StrictMode {/*detecting-impure-calculations-with-strict-mode*/}
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.
@ -197,7 +199,9 @@ If you've exhausted all other options and can't find the right event handler for
When possible, try to express your logic with rendering alone. You'll be surprised how far this can take you!
<DeepDive title="Why does React care about purity?">
<DeepDive>
#### Why does React care about purity? {/*why-does-react-care-about-purity*/}
Writing pure functions takes some habit and discipline. But it also unlocks marvelous opportunities:

4
beta/src/content/learn/lifecycle-of-reactive-effects.md

@ -573,7 +573,9 @@ In this example, `serverUrl` is not a prop or a state variable. It's a regular v
In other words, Effects "react" to all values from the component body.
<DeepDive title="Can global or mutable values be dependencies?">
<DeepDive>
#### Can global or mutable values be dependencies? {/*can-global-or-mutable-values-be-dependencies*/}
Mutable values (including global variables) aren't reactive.

14
beta/src/content/learn/manipulating-the-dom-with-refs.md

@ -191,7 +191,9 @@ li {
</Sandpack>
<DeepDive title="How to manage a list of refs using a ref callback">
<DeepDive>
#### How to manage a list of refs using a ref callback {/*how-to-manage-a-list-of-refs-using-a-ref-callback*/}
In the above examples, there is a predefined number of refs. However, sometimes you might need a ref to each item in the list, and you don't know how many you will have. Something like this **wouldn't work**:
@ -430,7 +432,9 @@ export default function Form() {
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 title="Exposing a subset of the API with an imperative handle">
<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`:
@ -491,7 +495,9 @@ React sets `ref.current` during the commit. Before updating the DOM, React sets
**Usually, you will access refs from event handlers.** If you want to do something with a ref, but there is no particular event to do it in, you might need an Effect. We will discuss effects on the next pages.
<DeepDive title="Flushing state updates synchronously with flushSync">
<DeepDive>
#### Flushing state updates synchronously with flushSync {/*flushing-state-updates-synchronously-with-flush-sync*/}
Consider code like this, which adds a new todo and scrolls the screen down to the last child of the list. Notice how, for some reason, it always scrolls to the todo that was *just before* the last added one:
@ -1193,4 +1199,4 @@ button { display: block; margin-bottom: 10px; }
</Solution>
</Challenges>
</Challenges>

4
beta/src/content/learn/preserving-and-resetting-state.md

@ -1233,7 +1233,9 @@ textarea {
</Sandpack>
<DeepDive title="Preserving state for removed components">
<DeepDive>
#### 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:

8
beta/src/content/learn/reacting-to-input-with-state.md

@ -238,7 +238,9 @@ export default function Form({
</Sandpack>
<DeepDive title="Displaying many visual states at once">
<DeepDive>
#### 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:
@ -387,7 +389,9 @@ const [status, setStatus] = useState('typing'); // 'typing', 'submitting', or 's
You know they are essential, because you can't remove any of them without breaking the functionality.
<DeepDive title="Eliminating “impossible” states with a reducer">
<DeepDive>
#### Eliminating “impossible” states with a reducer {/*eliminating-impossible-states-with-a-reducer*/}
These three variables are a good enough representation of this form's state. However, there are still some intermediate states that don't fully make sense. For example, a non-null `error` doesn't make sense when `status` is `'success'`. To model the state more precisely, you can [extract it into a reducer.](/learn/extracting-state-logic-into-a-reducer) Reducers let you unify multiple state variables into a single object and consolidate all the related logic!

4
beta/src/content/learn/referencing-values-with-refs.md

@ -234,7 +234,9 @@ export default function Counter() {
This is why reading `ref.current` during render leads to unreliable code. If you need that, use state instead.
<DeepDive title="How does useRef work inside?">
<DeepDive>
#### How does useRef work inside? {/*how-does-use-ref-work-inside*/}
Although both `useState` and `useRef` are provided by React, in principle `useRef` could be implemented _on top of_ `useState`. You can imagine that inside of React, `useRef` is implemented like this:

4
beta/src/content/learn/removing-effect-dependencies.md

@ -293,7 +293,9 @@ useEffect(() => {
</Pitfall>
<DeepDive title="Why is suppressing the dependency linter so dangerous?">
<DeepDive>
#### Why is suppressing the dependency linter so dangerous? {/*why-is-suppressing-the-dependency-linter-so-dangerous*/}
Suppressing the linter leads to very unintuitive bugs that are hard to find and fix. Here's one example:

4
beta/src/content/learn/render-and-commit.md

@ -138,7 +138,9 @@ Otherwise, you can encounter confusing bugs and unpredictable behavior as your c
</Pitfall>
<DeepDive title="Optimizing performance">
<DeepDive>
#### 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#gatsby-focus-wrapper) section. **Don't optimize prematurely!**

4
beta/src/content/learn/rendering-lists.md

@ -372,7 +372,9 @@ img { width: 100px; height: 100px; border-radius: 50%; }
</Sandpack>
<DeepDive title="Displaying several DOM nodes for each list item">
<DeepDive>
#### Displaying several DOM nodes for each list item {/*displaying-several-dom-nodes-for-each-list-item*/}
What do you do when each item needs to render not one, but several DOM nodes?

4
beta/src/content/learn/responding-to-events.md

@ -414,7 +414,9 @@ When you click on a button:
As a result of `e.stopPropagation()`, clicking on the buttons now only shows a single alert (from the `<button>`) rather than the two of them (from the `<button>` and the parent toolbar `<div>`). Clicking a button is not the same thing as clicking the surrounding toolbar, so stopping the propagation makes sense for this UI.
<DeepDive title="Capture phase events">
<DeepDive>
#### Capture phase events {/*capture-phase-events*/}
In rare cases, you might need to catch all events on child elements, *even if they stopped propagation*. For example, maybe you want to log every click to analytics, regardless of the propagation logic. You can do this by adding `Capture` at the end of the event name:

12
beta/src/content/learn/reusing-logic-with-custom-hooks.md

@ -234,7 +234,9 @@ If your linter is [configured for React,](/learn/editor-setup#linting) it will e
</Note>
<DeepDive title="Should all functions called during rendering start with the use prefix?">
<DeepDive>
#### Should all functions called during rendering start with the use prefix? {/*should-all-functions-called-during-rendering-start-with-the-use-prefix*/}
No. Functions that don't *call* Hooks don't need to *be* Hooks.
@ -1177,7 +1179,9 @@ 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. Ideally, with time, most of your app's Effects will be in custom Hooks.
<DeepDive title="Keep your custom Hooks focused on concrete high-level use cases">
<DeepDive>
#### Keep your custom Hooks focused on concrete high-level use cases {/*keep-your-custom-hooks-focused-on-concrete-high-level-use-cases*/}
Start by choosing your custom Hook's name. If you struggle to pick a clear name, it might mean that your Effect is too coupled to the rest of your component's logic, and is not yet ready to be extracted.
@ -1411,7 +1415,9 @@ This is another reason for why wrapping Effects in custom Hooks is often benefic
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. There are also many excellent custom Hooks maintained by the React community.
<DeepDive title="Will React provide any built-in solution for data fetching?">
<DeepDive>
#### Will React provide any built-in solution for data fetching? {/*will-react-provide-any-built-in-solution-for-data-fetching*/}
We're still working out the details, but we expect that in the future, you'll write data fetching like this:

4
beta/src/content/learn/separating-events-from-effects.md

@ -705,7 +705,9 @@ In this example, `url` inside `onVisit` corresponds to the *latest* `url` (which
</Note>
<DeepDive title="Is it okay to suppress the dependency linter instead?">
<DeepDive>
#### Is it okay to suppress the dependency linter instead? {/*is-it-okay-to-suppress-the-dependency-linter-instead*/}
In the existing codebases, you may sometimes see the lint rule suppressed like this:

4
beta/src/content/learn/sharing-state-between-components.md

@ -284,7 +284,9 @@ When `Accordion`'s `activeIndex` state changes to `1`, the second `Panel` receiv
</DiagramGroup>
<DeepDive title="Controlled and uncontrolled components">
<DeepDive>
#### 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.

4
beta/src/content/learn/state-a-components-memory.md

@ -518,7 +518,9 @@ button {
It is a good idea to have multiple state variables if their state is unrelated, like `index` and `showMore` in this example. But if you find that you often change two state variables together, it might be better to combine them into a single one. For example, if you have a form with many fields, it's more convenient to have a single state variable that holds an object than state variable per field. [Choosing the State Structure](/learn/choosing-the-state-structure) has more tips on this.
<DeepDive title="How does React know which state to return?">
<DeepDive>
#### How does React know which state to return? {/*how-does-react-know-which-state-to-return*/}
You might have noticed that the `useState` call does not receive any information about *which* state variable it refers to. There is no "identifier" that is passed to `useState`, so how does it know which of the state variables to return? Does it rely on some magic like parsing your functions? The answer is no.

12
beta/src/content/learn/synchronizing-with-effects.md

@ -423,7 +423,9 @@ We'll take a close look at what "mount" means in the next step.
</Pitfall>
<DeepDive title="Why was the ref omitted from the dependency array?">
<DeepDive>
#### Why was the ref omitted from the dependency array? {/*why-was-the-ref-omitted-from-the-dependency-array*/}
This Effect uses _both_ `ref` and `isPlaying`, but only `isPlaying` is declared as a dependency:
@ -688,7 +690,9 @@ function TodoList() {
This will not only improve the development experience, but also make your application feel faster. For example, the user pressing the Back button won't have to wait for some data to load again because it will be cached. You can either build such a cache yourself or use one of the many existing alternatives to manual fetching in Effects.
<DeepDive title="What are good alternatives to data fetching in Effects?">
<DeepDive>
#### What are good alternatives to data fetching in Effects? {/*what-are-good-alternatives-to-data-fetching-in-effects*/}
Writing `fetch` calls inside Effects is a [popular way to fetch data](https://www.robinwieruch.de/react-hooks-fetch-data/), especially in fully client-side apps. This is, however, a very manual approach and it has significant downsides:
@ -831,7 +835,9 @@ Finally, edit the component above and **comment out the cleanup function** so th
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).
<DeepDive title="Each render has its own Effects">
<DeepDive>
#### Each render has its own Effects {/*each-render-has-its-own-effects*/}
You can think of `useEffect` as "attaching" a piece of behavior to the render output. Consider this Effect:

4
beta/src/content/learn/thinking-in-react.md

@ -235,7 +235,9 @@ Let's go through them one by one again:
This means only the search text and the value of the checkbox are state! Nicely done!
<DeepDive title="Props vs State">
<DeepDive>
#### Props vs State {/*props-vs-state*/}
There are two types of "model" data in React: props and state. The two are very different:

20
beta/src/content/learn/updating-objects-in-state.md

@ -166,7 +166,9 @@ body { margin: 0; padding: 0; height: 250px; }
</Sandpack>
<DeepDive title="Local mutation is fine">
<DeepDive>
#### Local mutation is fine {/*local-mutation-is-fine*/}
Code like this is a problem because it modifies an *existing* object in state:
@ -371,7 +373,9 @@ input { margin-left: 5px; margin-bottom: 5px; }
Note that the `...` spread syntax is "shallow"--it only copies things one level deep. This makes it fast, but it also means that if you want to update a nested property, you'll have to use it more than once.
<DeepDive title="Using a single event handler for multiple fields">
<DeepDive>
#### Using a single event handler for multiple fields {/*using-a-single-event-handler-for-multiple-fields*/}
You can also use the `[` and `]` braces inside your object definition to specify a property with dynamic name. Here is the same example, but with a single event handler instead of three different ones:
@ -590,7 +594,9 @@ img { width: 200px; height: 200px; }
</Sandpack>
<DeepDive title="Objects are not really nested">
<DeepDive>
#### Objects are not really nested {/*objects-are-not-really-nested*/}
An object like this appears "nested" in code:
@ -656,7 +662,9 @@ updatePerson(draft => {
But unlike a regular mutation, it doesn't overwrite the past state!
<DeepDive title="How does Immer work?">
<DeepDive>
#### How does Immer work? {/*how-does-immer-work*/}
The `draft` provided by Immer is a special type of object, called a [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), that "records" what you do with it. This is why you can mutate it freely as much as you like! Under the hood, Immer figures out which parts of the `draft` have been changed, and produces a completely new object that contains your edits.
@ -783,7 +791,9 @@ img { width: 200px; height: 200px; }
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 title="Why is mutating state not recommended in React?">
<DeepDive>
#### Why is mutating state not recommended in React? {/*why-is-mutating-state-not-recommended-in-react*/}
There are a few reasons:

4
beta/src/content/learn/writing-markup-with-jsx.md

@ -171,7 +171,9 @@ If you don't want to add an extra `<div>` to your markup, you can write `<>` and
This empty tag is called a *[Fragment.](/apis/react/Fragment)* Fragments let you group things without leaving any trace in the browser HTML tree.
<DeepDive title="Why do multiple JSX tags need to be wrapped?">
<DeepDive>
#### Why do multiple JSX tags need to be wrapped? {/*why-do-multiple-jsx-tags-need-to-be-wrapped*/}
JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can't return two objects from a function without wrapping them into an array. This explains why you also can't return two JSX tags without wrapping them into another tag or a Fragment.

4
beta/src/content/learn/you-might-not-need-an-effect.md

@ -125,7 +125,9 @@ function TodoList({ todos, filter }) {
The function you wrap in [`useMemo`](/apis/react/useMemo) runs during rendering, so this only works for [pure calculations.](/learn/keeping-components-pure)
<DeepDive title="How to tell if a calculation is expensive?">
<DeepDive>
#### How to tell if a calculation is expensive? {/*how-to-tell-if-a-calculation-is-expensive*/}
In general, unless you're creating or looping over thousands of objects, it's probably not expensive. If you want to get more confidence, you can add a console log to measure the time spent in a piece of code:

6
beta/src/content/learn/your-first-component.md

@ -207,7 +207,9 @@ When a child component needs some data from a parent, [pass it by props](/learn/
</Pitfall>
<DeepDive title="Components all the way down">
<DeepDive>
#### 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 [Create React App](https://create-react-app.dev/), the root component is defined in `src/App.js`. 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.
@ -456,4 +458,4 @@ export default function Congratulations() {
</Solution>
</Challenges>
</Challenges>

Loading…
Cancel
Save