docs-components

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

MDX Component Patterns

MDX组件模式

Quick Reference

快速参考

Component Decision Tree

组件决策树

NeedComponent
Helpful tip or terminology
<Note>
Common mistake warning
<Pitfall>
Advanced technical explanation
<DeepDive>
Canary-only feature
<Canary>
or
<CanaryBadge />
Server Components only
<RSC>
Deprecated API
<Deprecated>
Experimental/WIP
<Wip>
Visual diagram
<Diagram>
Multiple related examples
<Recipes>
Interactive code
<Sandpack>
(see
/docs-sandpack
)
Console error display
<ConsoleBlock>
End-of-page exercises
<Challenges>
(Learn pages only)
需求组件
实用提示或术语说明
<Note>
常见错误警告
<Pitfall>
进阶技术讲解
<DeepDive>
仅Canary版本可用的功能
<Canary>
<CanaryBadge />
仅Server Components可用
<RSC>
已废弃的API
<Deprecated>
实验性/开发中功能
<Wip>
可视化图表
<Diagram>
多个相关示例
<Recipes>
交互式代码
<Sandpack>
(参见
/docs-sandpack
控制台错误展示
<ConsoleBlock>
页面末尾练习
<Challenges>
(仅Learn页面可用)

Heading Level Conventions

标题层级规范

ComponentHeading Level
DeepDive title
####
(h4)
Titled Pitfall
#####
(h5)
Titled Note
####
(h4)
Recipe items
####
(h4)
Challenge items
####
(h4)
组件标题层级
DeepDive标题
####
(h4)
带标题的Pitfall
#####
(h5)
带标题的Note
####
(h4)
Recipe条目
####
(h4)
Challenge条目
####
(h4)

Callout Spacing Rules

提示组件间距规则

Callout components (Note, Pitfall, DeepDive) require a blank line after the opening tag before content begins.
Never place consecutively:
  • <Pitfall>
    followed by
    <Pitfall>
    - Combine into one with titled subsections, or separate with prose
  • <Note>
    followed by
    <Note>
    - Combine into one, or separate with prose
Allowed consecutive patterns:
  • <DeepDive>
    followed by
    <DeepDive>
    - OK for multi-part explorations (see useMemo.md)
  • <Pitfall>
    followed by
    <DeepDive>
    - OK when DeepDive explains "why" behind the Pitfall
Separation content: Prose paragraphs, code examples (Sandpack), or section headers.
Why: Consecutive warnings create a "wall of cautions" that overwhelms readers and causes important warnings to be skimmed.
Incorrect:
mdx
<Pitfall>
Don't do X.
</Pitfall>

<Pitfall>
Don't do Y.
</Pitfall>
Correct - combined:
mdx
<Pitfall>
提示类组件(Note、Pitfall、DeepDive)要求在开始标签后留一个空行再写入内容。
禁止连续放置:
  • <Pitfall>
    紧跟
    <Pitfall>
    - 合并为一个组件并添加标题子章节,或用正文分隔
  • <Note>
    紧跟
    <Note>
    - 合并为一个组件,或用正文分隔
允许的连续模式:
  • <DeepDive>
    紧跟
    <DeepDive>
    - 适用于多部分深度探索场景(参见useMemo.md)
  • <Pitfall>
    紧跟
    <DeepDive>
    - 当DeepDive用于解释Pitfall背后的“原因”时允许
分隔内容: 正文段落、代码示例(Sandpack)或章节标题
原因: 连续的警告会形成“警示墙”,让读者感到 overwhelm,导致重要警告被忽略。
错误示例:
mdx
<Pitfall>
Don't do X.
</Pitfall>

<Pitfall>
Don't do Y.
</Pitfall>
正确示例 - 合并:
mdx
<Pitfall>
Don't do X {/pitfall-x/}
Don't do X {/pitfall-x/}
Explanation.
Explanation.
Don't do Y {/pitfall-y/}
Don't do Y {/pitfall-y/}
Explanation.
</Pitfall> ```
Correct - separated:
mdx
<Pitfall>
Don't do X.
</Pitfall>

This leads to another common mistake:

<Pitfall>
Don't do Y.
</Pitfall>

Explanation.
</Pitfall> ```
正确示例 - 分隔:
mdx
<Pitfall>
Don't do X.
</Pitfall>

This leads to another common mistake:

<Pitfall>
Don't do Y.
</Pitfall>

<Note>

<Note>

Important clarifications, conventions, or tips. Less severe than Pitfall.
重要的说明、规范或提示,严重程度低于Pitfall。

Simple Note

基础Note

mdx
<Note>

The optimization of caching return values is known as [_memoization_](https://en.wikipedia.org/wiki/Memoization).

</Note>
mdx
<Note>

缓存返回值的优化方式被称为[记忆化](https://en.wikipedia.org/wiki/Memoization)。

</Note>

Note with Title

带标题的Note

Use
####
(h4) heading with an ID.
mdx
<Note>
使用
####
(h4)标题并添加ID。
mdx
<Note>

There is no directive for Server Components. {/no-directive/}

没有针对Server Components的指令 {/no-directive/}

A common misunderstanding is that Server Components are denoted by
"use server"
, but there is no directive for Server Components. The
"use server"
directive is for Server Functions.
</Note> ```
一个常见误解是Server Components通过
"use server"
标识,但实际上没有专门针对Server Components的指令。
"use server"
指令是用于Server Functions的。
</Note> ```

Version-Specific Note

版本特定Note

mdx
<Note>

Starting in React 19, you can render `<SomeContext>` as a provider.

In older versions of React, use `<SomeContext.Provider>`.

</Note>

mdx
<Note>

从React 19开始,你可以直接渲染`<SomeContext>`作为提供者。

在旧版本React中,请使用`<SomeContext.Provider>`。

</Note>

<Pitfall>

<Pitfall>

Common mistakes that cause bugs. Use for errors readers will likely make.
会导致Bug的常见错误,用于提示读者很可能会犯的错误。

Simple Pitfall

基础Pitfall

mdx
<Pitfall>

We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)

</Pitfall>
mdx
<Pitfall>

我们建议将组件定义为函数而非类。[参见迁移方法](#alternatives)。

</Pitfall>

Titled Pitfall

带标题的Pitfall

Use
#####
(h5) heading with an ID.
mdx
<Pitfall>
使用
#####
(h5)标题并添加ID。
mdx
<Pitfall>
Calling different memoized functions will read from different caches. {/pitfall-different-caches/}
调用不同的记忆化函数会读取不同的缓存 {/pitfall-different-caches/}
To access the same cache, components must call the same memoized function.
</Pitfall> ```
要访问同一个缓存,组件必须调用同一个记忆化函数。
</Pitfall> ```

Pitfall with Wrong/Right Code

包含错误/正确代码的Pitfall

mdx
<Pitfall>
mdx
<Pitfall>
useFormStatus
will not return status information for a
<form>
rendered in the same component. {/pitfall-same-component/}
useFormStatus
不会返回同一组件中渲染的
<form>
的状态信息 {/pitfall-same-component/}
js
function Form() {
  // 🔴 `pending` will never be true
  const { pending } = useFormStatus();
  return <form action={submit}></form>;
}
Instead call
useFormStatus
from inside a component located inside
<form>
.
</Pitfall> ```
js
function Form() {
  // 🔴 `pending`永远不会为true
  const { pending } = useFormStatus();
  return <form action={submit}></form>;
}
请改为从
<form>
内部的组件中调用
useFormStatus
</Pitfall> ```

<DeepDive>

<DeepDive>

Optional deep technical content. First child must be
####
heading with ID.
可选的深度技术内容。第一个子元素必须是带ID的
####
标题。

Standard DeepDive

标准DeepDive

mdx
<DeepDive>
mdx
<DeepDive>

Is using an updater always preferred? {/is-updater-preferred/}

是否总是优先使用更新器函数? {/is-updater-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's no harm in it, but it's also not always necessary.
In most cases, there is no difference between these two approaches. React always makes sure that for intentional user actions, like clicks, the
age
state variable would be updated before the next click.
</DeepDive> ```
你可能听过这样的建议:如果要设置的状态是基于之前的状态计算的,应该始终使用
setAge(a => a + 1)
这样的写法。这种写法没有坏处,但也并非总是必要的。
在大多数情况下,这两种写法没有区别。React始终确保对于用户的主动操作(如点击),
age
状态变量会在下次点击前完成更新。
</DeepDive> ```

Comparison DeepDive

对比式DeepDive

For comparing related concepts:
mdx
<DeepDive>
用于对比相关概念:
mdx
<DeepDive>

When should I use
cache
,
memo
, or
useMemo
? {/cache-memo-usememo/}

何时应该使用
cache
memo
useMemo
? {/cache-memo-usememo/}

All mentioned APIs offer memoization but differ in what they memoize, who can access the cache, and when their cache is invalidated.
上述所有API都提供记忆化功能,但它们在记忆化对象、缓存可访问范围和缓存失效时机上有所不同。

useMemo
{/deep-dive-usememo/}

useMemo
{/deep-dive-usememo/}

In general, you should use
useMemo
for caching expensive computations in Client Components across renders.
通常,你应该在Client Components中使用
useMemo
来缓存跨渲染的昂贵计算。

cache
{/deep-dive-cache/}

cache
{/deep-dive-cache/}

In general, you should use
cache
in Server Components to memoize work that can be shared across components.
</DeepDive> ```
通常,你应该在Server Components中使用
cache
来记忆化可在组件间共享的操作。
</DeepDive> ```

<Recipes>

<Recipes>

Multiple related examples showing variations. Each recipe needs
<Solution />
.
mdx
<Recipes titleText="Basic useState examples" titleId="examples-basic">
展示变体的多个相关示例。每个Recipe需要包含
<Solution />
mdx
<Recipes titleText="Basic useState examples" titleId="examples-basic">

Counter (number) {/counter-number/}

计数器(数字类型) {/counter-number/}

In this example, the
count
state variable holds a number.
<Sandpack> {/* code */} </Sandpack> <Solution />
在这个示例中,
count
状态变量存储一个数字。
<Sandpack> {/* code */} </Sandpack> <Solution />

Text field (string) {/text-field-string/}

文本输入框(字符串类型) {/text-field-string/}

In this example, the
text
state variable holds a string.
<Sandpack> {/* code */} </Sandpack> <Solution /> </Recipes> ```
Common titleText/titleId combinations:
  • "Basic [hookName] examples" /
    examples-basic
  • "Examples of [concept]" /
    examples-[concept]
  • "The difference between [A] and [B]" /
    examples-[topic]

在这个示例中,
text
状态变量存储一个字符串。
<Sandpack> {/* code */} </Sandpack> <Solution /> </Recipes> ```
常见titleText/titleId组合:
  • "Basic [hookName] examples" /
    examples-basic
  • "Examples of [concept]" /
    examples-[concept]
  • "The difference between [A] and [B]" /
    examples-[topic]

<Challenges>

<Challenges>

End-of-page exercises. Learn pages only. Each challenge needs problem + solution Sandpack.
mdx
<Challenges>
页面末尾的练习。**仅适用于Learn页面。**每个Challenge需要包含问题和解决方案Sandpack。
mdx
<Challenges>

Fix the bug {/fix-the-bug/}

修复Bug {/fix-the-bug/}

Problem description...
<Hint> Optional hint text. </Hint> <Sandpack> {/* problem code */} </Sandpack> <Solution>
Explanation...
<Sandpack> {/* solution code */} </Sandpack> </Solution> </Challenges> ```
Guidelines:
  • Only at end of standard Learn pages
  • No Challenges in chapter intros or tutorials
  • Each challenge has
    ####
    heading with ID

问题描述...
<Hint> 可选提示文本。 </Hint> <Sandpack> {/* problem code */} </Sandpack> <Solution>
解释...
<Sandpack> {/* solution code */} </Sandpack> </Solution> </Challenges> ```
规范:
  • 仅能放在标准Learn页面的末尾
  • 章节介绍或教程中不能使用Challenges
  • 每个Challenge包含带ID的
    ####
    标题

<Deprecated>

<Deprecated>

For deprecated APIs. Content should explain what to use instead.
用于已废弃的API。内容应说明替代方案。

Page-Level Deprecation

页面级废弃提示

mdx
<Deprecated>

In React 19, `forwardRef` is no longer necessary. Pass `ref` as a prop instead.

`forwardRef` will be deprecated in a future release. Learn more [here](/blog/2024/04/25/react-19#ref-as-a-prop).

</Deprecated>
mdx
<Deprecated>

在React 19中,`forwardRef`不再是必需的。直接将`ref`作为props传递即可。

`forwardRef`将在未来版本中被废弃。了解更多[此处](/blog/2024/04/25/react-19#ref-as-a-prop)。

</Deprecated>

Method-Level Deprecation

方法级废弃提示

mdx
undefined
mdx
undefined

componentWillMount()
{/componentwillmount/}

componentWillMount()
{/componentwillmount/}

<Deprecated>
This API has been renamed from
componentWillMount
to
UNSAFE_componentWillMount
.
Run the
rename-unsafe-lifecycles
codemod
to automatically update.
</Deprecated> ```
<Deprecated>
该API已从
componentWillMount
重命名为
UNSAFE_componentWillMount
运行
rename-unsafe-lifecycles
代码转换工具
可自动更新。
</Deprecated> ```

<RSC>

<RSC>

For APIs that only work with React Server Components.
仅适用于React Server Components的API。

Basic RSC

基础RSC提示

mdx
<RSC>

`cache` is only for use with [React Server Components](/reference/rsc/server-components).

</RSC>
mdx
<RSC>

`cache`仅适用于[React Server Components](/reference/rsc/server-components)。

</RSC>

Extended RSC (for Server Functions)

扩展RSC提示(针对Server Functions)

mdx
<RSC>

Server Functions are for use in [React Server Components](/reference/rsc/server-components).

**Note:** Until September 2024, we referred to all Server Functions as "Server Actions".

</RSC>

mdx
<RSC>

Server Functions适用于[React Server Components](/reference/rsc/server-components)。

**注意:** 截至2024年9月,我们曾将所有Server Functions称为"Server Actions"。

</RSC>

<Canary>
and
<CanaryBadge />

<Canary>
<CanaryBadge />

For features only available in Canary releases.
仅在Canary版本中可用的功能。

Canary Wrapper (inline in Intro)

Canary包裹组件(在Intro中内联使用)

mdx
<Intro>

`<Fragment>` lets you group elements without a wrapper node.

<Canary>Fragments can also accept refs, enabling interaction with underlying DOM nodes.</Canary>

</Intro>
mdx
<Intro>

`<Fragment>`允许你在不使用包裹节点的情况下分组元素。

<Canary>Fragments现在也可以接收refs,支持与底层DOM节点交互。</Canary>

</Intro>

CanaryBadge in Section Headings

章节标题中的CanaryBadge

mdx
undefined
mdx
undefined

<CanaryBadge /> FragmentInstance {/fragmentinstance/}

<CanaryBadge /> FragmentInstance {/fragmentinstance/}

undefined
undefined

CanaryBadge in Props Lists

属性列表中的CanaryBadge

mdx
* <CanaryBadge /> **optional** `ref`: A ref object from `useRef` or callback function.
mdx
* <CanaryBadge /> **可选** `ref`: 来自`useRef`的ref对象或回调函数。

CanaryBadge in Caveats

注意事项中的CanaryBadge

mdx
* <CanaryBadge /> If you want to pass `ref` to a Fragment, you can't use the `<>...</>` syntax.

mdx
* <CanaryBadge /> 如果你想给Fragment传递`ref`,不能使用`<>...</>`语法。

<Diagram>

<Diagram>

Visual explanations of module dependencies, render trees, or data flow.
mdx
<Diagram name="use_client_module_dependency" height={250} width={545} alt="A tree graph with the top node representing the module 'App.js'. 'App.js' has three children...">
`'use client'` segments the module dependency tree, marking `InspirationGenerator.js` and all dependencies as client-rendered.
</Diagram>
Attributes:
  • name
    : Diagram identifier (used for image file)
  • height
    : Height in pixels
  • width
    : Width in pixels
  • alt
    : Accessible description of the diagram

用于可视化解释模块依赖、渲染树或数据流。
mdx
<Diagram name="use_client_module_dependency" height={250} width={545} alt="树状图,顶部节点代表模块'App.js'。'App.js'有三个子节点...">
`'use client'`会分割模块依赖树,标记`InspirationGenerator.js`及其所有依赖为客户端渲染。
</Diagram>
属性:
  • name
    : 图表标识符(用于图片文件)
  • height
    : 高度(像素)
  • width
    : 宽度(像素)
  • alt
    : 图表的无障碍描述

<CodeStep>
(Use Sparingly)

<CodeStep>
(谨慎使用)

Numbered callouts in prose. Pairs with code block annotations.
正文中的编号标注,与代码块注释配合使用。

Syntax

语法

In code blocks:
mdx
```js [[1, 4, "age"], [2, 4, "setAge"], [3, 4, "42"]]
import { useState } from 'react';

function MyComponent() {
  const [age, setAge] = useState(42);
}

Format: `[[step_number, line_number, "text_to_highlight"], ...]`

In prose:
```mdx
1. The <CodeStep step={1}>current state</CodeStep> initially set to the <CodeStep step={3}>initial value</CodeStep>.
2. The <CodeStep step={2}>`set` function</CodeStep> that lets you change it.
代码块中:
mdx
```js [[1, 4, "age"], [2, 4, "setAge"], [3, 4, "42"]]
import { useState } from 'react';

function MyComponent() {
  const [age, setAge] = useState(42);
}

格式:`[[step_number, line_number, "text_to_highlight"], ...]`

正文中:
```mdx
1. <CodeStep step={1}>当前状态</CodeStep>初始设置为<CodeStep step={3}>初始值</CodeStep>。
2. <CodeStep step={2}>`set`函数</CodeStep>用于修改状态。

Guidelines

规范

  • Maximum 2-3 different colors per explanation
  • Don't highlight every keyword - only key concepts
  • Use for terms in prose, not entire code blocks
  • Maintain consistent usage within a section
Good use - highlighting key concepts:
mdx
React will compare the <CodeStep step={2}>dependencies</CodeStep> with the dependencies you passed...
🚫 Avoid - excessive highlighting:
mdx
When an <CodeStep step={1}>Activity</CodeStep> boundary is <CodeStep step={2}>hidden</CodeStep> during its <CodeStep step={3}>initial</CodeStep> render...

  • 每个解释最多使用2-3种不同颜色
  • 不要高亮每个关键词,仅高亮核心概念
  • 用于正文中的术语,而非整个代码块
  • 同一章节内保持使用一致性
合理用法 - 高亮核心概念:
mdx
React会将<CodeStep step={2}>依赖项</CodeStep>与你之前传递的依赖项进行比较...
🚫 避免 - 过度高亮:
mdx
当<CodeStep step={1}>Activity</CodeStep>边界在<CodeStep step={3}>初始</CodeStep>渲染时被<CodeStep step={2}>隐藏</CodeStep>...

<ConsoleBlock>

<ConsoleBlock>

Display console output (errors, warnings, logs).
mdx
<ConsoleBlock level="error">
Uncaught Error: Too many re-renders.
</ConsoleBlock>
Levels:
error
,
warning
,
info

展示控制台输出(错误、警告、日志)。
mdx
<ConsoleBlock level="error">
Uncaught Error: Too many re-renders.
</ConsoleBlock>
级别:
error
,
warning
,
info

Component Usage by Page Type

按页面类型区分的组件用法

Reference Pages

参考页面

For component placement rules specific to Reference pages, invoke
/docs-writer-reference
.
Key placement patterns:
  • <RSC>
    goes before
    <Intro>
    at top of page
  • <Deprecated>
    goes after
    <Intro>
    for page-level deprecation
  • <Deprecated>
    goes after method heading for method-level deprecation
  • <Canary>
    wrapper goes inline within
    <Intro>
  • <CanaryBadge />
    appears in headings, props lists, and caveats
关于参考页面的组件放置规则,请调用
/docs-writer-reference
核心放置模式:
  • <RSC>
    放在页面顶部的
    <Intro>
    之前
  • 页面级废弃提示的
    <Deprecated>
    放在
    <Intro>
    之后
  • 方法级废弃提示的
    <Deprecated>
    放在方法标题之后
  • <Canary>
    包裹组件内联在
    <Intro>
  • <CanaryBadge />
    出现在标题、属性列表和注意事项中

Learn Pages

Learn页面

For Learn page structure and patterns, invoke
/docs-writer-learn
.
Key usage patterns:
  • Challenges only at end of standard Learn pages
  • No Challenges in chapter intros or tutorials
  • DeepDive for optional advanced content
  • CodeStep should be used sparingly
关于Learn页面的结构和模式,请调用
/docs-writer-learn
核心用法模式:
  • Challenges仅能放在标准Learn页面的末尾
  • 章节介绍或教程中不能使用Challenges
  • DeepDive用于可选的进阶内容
  • CodeStep应谨慎使用

Blog Pages

博客页面

For Blog page structure and patterns, invoke
/docs-writer-blog
.
Key usage patterns:
  • Generally avoid deep technical components
  • Note and Pitfall OK for clarifications
  • Prefer inline explanations over DeepDive

关于博客页面的结构和模式,请调用
/docs-writer-blog
核心用法模式:
  • 通常避免使用深度技术组件
  • Note和Pitfall可用于说明
  • 优先使用内联解释而非DeepDive

Other Available Components

其他可用组件

Version/Status:
<Experimental>
,
<ExperimentalBadge />
,
<RSCBadge />
,
<NextMajor>
,
<Wip>
Visuals:
<DiagramGroup>
,
<Illustration>
,
<IllustrationBlock>
,
<CodeDiagram>
,
<FullWidth>
Console:
<ConsoleBlockMulti>
,
<ConsoleLogLine>
Specialized:
<TerminalBlock>
,
<BlogCard>
,
<TeamMember>
,
<YouTubeIframe>
,
<ErrorDecoder />
,
<LearnMore>
,
<Math>
,
<MathI>
,
<LanguageList>
See existing docs for usage examples of these components.
版本/状态类:
<Experimental>
,
<ExperimentalBadge />
,
<RSCBadge />
,
<NextMajor>
,
<Wip>
视觉类:
<DiagramGroup>
,
<Illustration>
,
<IllustrationBlock>
,
<CodeDiagram>
,
<FullWidth>
控制台类:
<ConsoleBlockMulti>
,
<ConsoleLogLine>
特殊类:
<TerminalBlock>
,
<BlogCard>
,
<TeamMember>
,
<YouTubeIframe>
,
<ErrorDecoder />
,
<LearnMore>
,
<Math>
,
<MathI>
,
<LanguageList>
请参考现有文档获取这些组件的用法示例。