From cb9854a54984ef1288a8a2b8754897b15e75f433 Mon Sep 17 00:00:00 2001 From: Jing Jiawei <30466424+ibarapascal@users.noreply.github.com> Date: Sat, 3 Dec 2022 06:35:27 +0900 Subject: [PATCH] [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 Co-authored-by: dan Co-authored-by: Fuqiao Xue Co-authored-by: Andrew Clark --- beta/src/components/MDX/ExpandableExample.tsx | 32 +++++++++++-------- beta/src/content/apis/react/Children.md | 4 ++- beta/src/content/apis/react/Fragment.md | 4 ++- beta/src/content/apis/react/createElement.md | 4 ++- beta/src/content/apis/react/isValidElement.md | 4 ++- beta/src/content/apis/react/memo.md | 4 ++- beta/src/content/apis/react/useCallback.md | 8 +++-- .../content/apis/react/useDeferredValue.md | 8 +++-- beta/src/content/apis/react/useEffect.md | 4 ++- beta/src/content/apis/react/useId.md | 4 ++- beta/src/content/apis/react/useMemo.md | 12 +++++-- beta/src/content/apis/react/useRef.md | 4 ++- beta/src/content/apis/react/useState.md | 4 ++- .../content/learn/add-react-to-a-website.md | 4 ++- .../learn/choosing-the-state-structure.md | 8 +++-- .../content/learn/conditional-rendering.md | 6 ++-- .../extracting-state-logic-into-a-reducer.md | 4 ++- .../importing-and-exporting-components.md | 6 ++-- .../content/learn/keeping-components-pure.md | 8 +++-- .../learn/lifecycle-of-reactive-effects.md | 4 ++- .../learn/manipulating-the-dom-with-refs.md | 14 +++++--- .../learn/preserving-and-resetting-state.md | 4 ++- .../learn/reacting-to-input-with-state.md | 8 +++-- .../learn/referencing-values-with-refs.md | 4 ++- .../learn/removing-effect-dependencies.md | 4 ++- beta/src/content/learn/render-and-commit.md | 4 ++- beta/src/content/learn/rendering-lists.md | 4 ++- .../src/content/learn/responding-to-events.md | 4 ++- .../learn/reusing-logic-with-custom-hooks.md | 12 +++++-- .../learn/separating-events-from-effects.md | 4 ++- .../learn/sharing-state-between-components.md | 4 ++- .../learn/state-a-components-memory.md | 4 ++- .../learn/synchronizing-with-effects.md | 12 +++++-- beta/src/content/learn/thinking-in-react.md | 4 ++- .../learn/updating-objects-in-state.md | 20 +++++++++--- .../content/learn/writing-markup-with-jsx.md | 4 ++- .../learn/you-might-not-need-an-effect.md | 4 ++- .../src/content/learn/your-first-component.md | 6 ++-- 38 files changed, 185 insertions(+), 71 deletions(-) diff --git a/beta/src/components/MDX/ExpandableExample.tsx b/beta/src/components/MDX/ExpandableExample.tsx index 435f9142..2baf9b4e 100644 --- a/beta/src/components/MDX/ExpandableExample.tsx +++ b/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 (
{ - // 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(); + } }}>
-

- {title} -

+

+ {children[0].props.children} +

{excerpt &&
{excerpt}
}
); diff --git a/beta/src/content/apis/react/Children.md b/beta/src/content/apis/react/Children.md index a4f7772f..ea573e63 100644 --- a/beta/src/content/apis/react/Children.md +++ b/beta/src/content/apis/react/Children.md @@ -126,7 +126,9 @@ export default function RowList({ children }) { - + + +#### 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. diff --git a/beta/src/content/apis/react/Fragment.md b/beta/src/content/apis/react/Fragment.md index e43ce2a2..4ccfe75a 100644 --- a/beta/src/content/apis/react/Fragment.md +++ b/beta/src/content/apis/react/Fragment.md @@ -74,7 +74,9 @@ function PostBody({ body }) { - + + +#### 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: diff --git a/beta/src/content/apis/react/createElement.md b/beta/src/content/apis/react/createElement.md index 9cc74a8f..871187f3 100644 --- a/beta/src/content/apis/react/createElement.md +++ b/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. - + + +#### 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 `` and `createElement(Greeting, { name: 'Taylor' })` produce an object like this: diff --git a/beta/src/content/apis/react/isValidElement.md b/beta/src/content/apis/react/isValidElement.md index e8408ef1..2f905922 100644 --- a/beta/src/content/apis/react/isValidElement.md +++ b/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. - + + +#### 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: diff --git a/beta/src/content/apis/react/memo.md b/beta/src/content/apis/react/memo.md index 58d5a858..700a7bee 100644 --- a/beta/src/content/apis/react/memo.md +++ b/beta/src/content/apis/react/memo.md @@ -80,7 +80,9 @@ label { - + + +#### 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. diff --git a/beta/src/content/apis/react/useCallback.md b/beta/src/content/apis/react/useCallback.md index 0780dbd2..52645496 100644 --- a/beta/src/content/apis/react/useCallback.md +++ b/beta/src/content/apis/react/useCallback.md @@ -124,7 +124,9 @@ function ProductPage({ productId, referrer, theme }) { - + + +#### 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) { - + + +#### 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. diff --git a/beta/src/content/apis/react/useDeferredValue.md b/beta/src/content/apis/react/useDeferredValue.md index f82bc1b1..77bd1003 100644 --- a/beta/src/content/apis/react/useDeferredValue.md +++ b/beta/src/content/apis/react/useDeferredValue.md @@ -457,7 +457,9 @@ input { margin: 10px; } - + + +#### 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 - + + +#### 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: diff --git a/beta/src/content/apis/react/useEffect.md b/beta/src/content/apis/react/useEffect.md index 547e3e87..b93af429 100644 --- a/beta/src/content/apis/react/useEffect.md +++ b/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) - + + +#### 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: diff --git a/beta/src/content/apis/react/useId.md b/beta/src/content/apis/react/useId.md index 0a348870..b4af065a 100644 --- a/beta/src/content/apis/react/useId.md +++ b/beta/src/content/apis/react/useId.md @@ -139,7 +139,9 @@ input { margin: 5px; } - + + +#### 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++`. diff --git a/beta/src/content/apis/react/useMemo.md b/beta/src/content/apis/react/useMemo.md index 8cf33401..3abcdd8a 100644 --- a/beta/src/content/apis/react/useMemo.md +++ b/beta/src/content/apis/react/useMemo.md @@ -61,7 +61,9 @@ Usually, this isn't a problem because most calculations are very fast. However, - + + +#### 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 - + + +#### 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. - + + +#### Memoizing individual JSX nodes {/*memoizing-individual-jsx-nodes*/} Instead of wrapping `List` in [`memo`](/apis/react/memo), you could wrap the `` JSX node itself in `useMemo`: diff --git a/beta/src/content/apis/react/useRef.md b/beta/src/content/apis/react/useRef.md index f76818cb..83e88ed8 100644 --- a/beta/src/content/apis/react/useRef.md +++ b/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. - + + +#### 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: diff --git a/beta/src/content/apis/react/useState.md b/beta/src/content/apis/react/useState.md index 7a7df1d2..d24063f4 100644 --- a/beta/src/content/apis/react/useState.md +++ b/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) - + + +#### 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. diff --git a/beta/src/content/learn/add-react-to-a-website.md b/beta/src/content/learn/add-react-to-a-website.md index dc313e17..c6036850 100644 --- a/beta/src/content/learn/add-react-to-a-website.md +++ b/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) - + + +#### 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: diff --git a/beta/src/content/learn/choosing-the-state-structure.md b/beta/src/content/learn/choosing-the-state-structure.md index 3231a70f..70969d3f 100644 --- a/beta/src/content/learn/choosing-the-state-structure.md +++ b/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. - + + +#### 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. - + + +#### 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. diff --git a/beta/src/content/learn/conditional-rendering.md b/beta/src/content/learn/conditional-rendering.md index 350a2a98..a0486d24 100644 --- a/beta/src/content/learn/conditional-rendering.md +++ b/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`"*. - + + +#### 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 `
  • `. 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() { - \ No newline at end of file + diff --git a/beta/src/content/learn/extracting-state-logic-into-a-reducer.md b/beta/src/content/learn/extracting-state-logic-into-a-reducer.md index a3f835fc..a4b0ac94 100644 --- a/beta/src/content/learn/extracting-state-logic-into-a-reducer.md +++ b/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 - + + +#### 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. diff --git a/beta/src/content/learn/importing-and-exporting-components.md b/beta/src/content/learn/importing-and-exporting-components.md index c646ba2e..5aedc2df 100644 --- a/beta/src/content/learn/importing-and-exporting-components.md +++ b/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 - + + +#### 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; } - \ No newline at end of file + diff --git a/beta/src/content/learn/keeping-components-pure.md b/beta/src/content/learn/keeping-components-pure.md index dda08c34..f3096115 100644 --- a/beta/src/content/learn/keeping-components-pure.md +++ b/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 y = 2x before or after y = 5x: 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! - + + +#### 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! - + + +#### 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: diff --git a/beta/src/content/learn/lifecycle-of-reactive-effects.md b/beta/src/content/learn/lifecycle-of-reactive-effects.md index 79ecd540..00b6fa04 100644 --- a/beta/src/content/learn/lifecycle-of-reactive-effects.md +++ b/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. - + + +#### Can global or mutable values be dependencies? {/*can-global-or-mutable-values-be-dependencies*/} Mutable values (including global variables) aren't reactive. diff --git a/beta/src/content/learn/manipulating-the-dom-with-refs.md b/beta/src/content/learn/manipulating-the-dom-with-refs.md index a17ff5e4..f3fe7d05 100644 --- a/beta/src/content/learn/manipulating-the-dom-with-refs.md +++ b/beta/src/content/learn/manipulating-the-dom-with-refs.md @@ -191,7 +191,9 @@ li { - + + +#### 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. - + + +#### 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. - + + +#### 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; } - \ No newline at end of file + diff --git a/beta/src/content/learn/preserving-and-resetting-state.md b/beta/src/content/learn/preserving-and-resetting-state.md index 24356963..22ebfc22 100644 --- a/beta/src/content/learn/preserving-and-resetting-state.md +++ b/beta/src/content/learn/preserving-and-resetting-state.md @@ -1233,7 +1233,9 @@ textarea { - + + +#### 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: diff --git a/beta/src/content/learn/reacting-to-input-with-state.md b/beta/src/content/learn/reacting-to-input-with-state.md index ba112c34..8d748a5d 100644 --- a/beta/src/content/learn/reacting-to-input-with-state.md +++ b/beta/src/content/learn/reacting-to-input-with-state.md @@ -238,7 +238,9 @@ 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: @@ -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. - + + +#### 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! diff --git a/beta/src/content/learn/referencing-values-with-refs.md b/beta/src/content/learn/referencing-values-with-refs.md index fe196493..f395ab87 100644 --- a/beta/src/content/learn/referencing-values-with-refs.md +++ b/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. - + + +#### 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: diff --git a/beta/src/content/learn/removing-effect-dependencies.md b/beta/src/content/learn/removing-effect-dependencies.md index 364fa497..289ef1d0 100644 --- a/beta/src/content/learn/removing-effect-dependencies.md +++ b/beta/src/content/learn/removing-effect-dependencies.md @@ -293,7 +293,9 @@ useEffect(() => { - + + +#### 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: diff --git a/beta/src/content/learn/render-and-commit.md b/beta/src/content/learn/render-and-commit.md index c8bfccbb..ea593873 100644 --- a/beta/src/content/learn/render-and-commit.md +++ b/beta/src/content/learn/render-and-commit.md @@ -138,7 +138,9 @@ 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#gatsby-focus-wrapper) section. **Don't optimize prematurely!** diff --git a/beta/src/content/learn/rendering-lists.md b/beta/src/content/learn/rendering-lists.md index 28dc75ef..9f3aa4e4 100644 --- a/beta/src/content/learn/rendering-lists.md +++ b/beta/src/content/learn/rendering-lists.md @@ -372,7 +372,9 @@ img { width: 100px; height: 100px; border-radius: 50%; } - + + +#### 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? diff --git a/beta/src/content/learn/responding-to-events.md b/beta/src/content/learn/responding-to-events.md index fd7cda47..830ecacb 100644 --- a/beta/src/content/learn/responding-to-events.md +++ b/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 `