关于 docs-components
docs-components 是面向文档作者的 MDX 组件规范 Skill,介绍如何选择组件、设置标题与间距,并说明 Reference、Learn 和博客页面的组件放置规则。
主要功能
- 01按文档需求选择组件
- 02遵循标题和间距规范
- 03规范提示框与代码示例
- 04参考不同页面类型的放置规则
适用场景
- 01在 MDX 文档中添加说明或警告
- 02组织进阶技术解释
- 03记录弃用或 Canary API
- 04编排 Learn 页面的练习
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ reactjs/ react.dev --skill docs-components安装后在 Claude Code 中输入/docs-components确认已加载。
详细介绍
MDX 组件模式
快速参考
组件决策树
| 需求 | 组件 |
|---|---|
| 实用提示或术语说明 | <Note> |
| 常见错误警告 | <Pitfall> |
| 高级技术说明 | <DeepDive> |
| 仅限 Canary 的功能 | <Canary> 或 <CanaryBadge /> |
| 仅限 Server Components | <RSC> |
| 已弃用的 API | <Deprecated> |
| 实验性/WIP 功能 | <Wip> |
| 可视化图表 | <Diagram> |
| 多个相关示例 | <Recipes> |
| 交互式代码 | <Sandpack>(参见 /docs-sandpack) |
| 控制台错误展示 | <ConsoleBlock> |
| 页面末尾练习 | <Challenges>(仅限 Learn 页面) |
标题级别约定
| 组件 | 标题级别 |
|---|---|
| DeepDive 标题 | #### (h4) |
| 带标题的 Pitfall | ##### (h5) |
| 带标题的 Note | #### (h4) |
| Recipe 条目 | #### (h4) |
| Challenge 条目 | #### (h4) |
提示框间距规则
提示框组件(Note、Pitfall、DeepDive)的开始标签后必须空一行,再开始正文。
切勿连续放置:
<Pitfall>后紧接<Pitfall>——合并为一个并使用带标题的小节,或在两者之间加入正文<Note>后紧接<Note>——合并为一个,或在两者之间加入正文
允许连续放置的模式:
<DeepDive>后紧接<DeepDive>——多部分深入探讨时可以这样做(参见 useMemo.md)<Pitfall>后紧接<DeepDive>——当 DeepDive 解释 Pitfall 背后的“原因”时可以这样做
**用于分隔的内容:**正文段落、代码示例(Sandpack)或章节标题。
**原因:**连续的警告会形成“警告墙”,让读者不堪其扰,并导致重要警告被略读。
错误示例:
<Pitfall>
Don't do X.
</Pitfall>
<Pitfall>
Don't do Y.
</Pitfall>
正确示例——合并:
<Pitfall>
##### Don't do X {/*pitfall-x*/}
Explanation.
##### Don't do Y {/*pitfall-y*/}
Explanation.
</Pitfall>
正确示例——分隔:
<Pitfall>
Don't do X.
</Pitfall>
This leads to another common mistake:
<Pitfall>
Don't do Y.
</Pitfall>
<Note>
用于重要的澄清说明、约定或提示。严重程度低于 Pitfall。
简单 Note
<Note>
The optimization of caching return values is known as [_memoization_](https://en.wikipedia.org/wiki/Memoization).
</Note>
带标题的 Note
使用带 ID 的 #### (h4) 标题。
<Note>
#### There is no directive for 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>
特定版本的 Note
<Note>
Starting in React 19, you can render `<SomeContext>` as a provider.
In older versions of React, use `<SomeContext.Provider>`.
</Note>
<Pitfall>
用于会导致错误的常见失误,适用于读者很可能会犯的错误。
简单 Pitfall
<Pitfall>
We recommend defining components as functions instead of classes. [See how to migrate.](#alternatives)
</Pitfall>
带标题的 Pitfall
使用带 ID 的 ##### (h5) 标题。
<Pitfall>
##### Calling different memoized functions will read from different caches. {/*pitfall-different-caches*/}
To access the same cache, components must call the same memoized function.
</Pitfall>
带错误/正确代码的 Pitfall
<Pitfall>
##### `useFormStatus` will not return status information for a `<form>` rendered in the same component. {/*pitfall-same-component*/}
```js
function Form() {
// 🔴 `pending` will never be true
const { pending } = useFormStatus();
return <form action={submit}></form>;
}
请改为在位于 <form> 内部的组件中调用 useFormStatus。
<DeepDive>
Optional deep technical content. First child must be #### heading with ID.
Standard DeepDive
<DeepDive>
#### Is using an updater always 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>
比较型 DeepDive
用于比较相关概念:
<DeepDive>
#### When should I use `cache`, `memo`, or `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.
#### `useMemo` {/*deep-dive-usememo*/}
In general, you should use `useMemo` for caching expensive computations in Client Components across renders.
#### `cache` {/*deep-dive-cache*/}
In general, you should use `cache` in Server Components to memoize work that can be shared across components.
</DeepDive>
<Recipes>
展示多种变化形式的相关示例。每个 recipe 都需要 <Solution />。
<Recipes titleText="Basic useState examples" titleId="examples-basic">
#### Counter (number) {/*counter-number*/}
In this example, the `count` state variable holds a number.
<Sandpack>
{/* code */}
</Sandpack>
<Solution />
#### Text field (string) {/*text-field-string*/}
In this example, the `text` state variable holds a string.
<Sandpack>
{/* code */}
</Sandpack>
<Solution />
</Recipes>
常见的 titleText/titleId 组合:
- "Basic [hookName] examples" /
examples-basic - "[concept] 的示例" /
examples-[concept] - "[A] 和 [B] 的区别" /
examples-[topic]
<Challenges>
页面末尾的练习。**仅限 Learn 页面。**每个 challenge 都需要问题和 solution Sandpack。
<Challenges>
#### Fix the bug {/*fix-the-bug*/}
Problem description...
<Hint>
Optional hint text.
</Hint>
<Sandpack>
{/* problem code */}
</Sandpack>
<Solution>
Explanation...
<Sandpack>
{/* solution code */}
</Sandpack>
</Solution>
</Challenges>
指南:
- 仅放在标准 Learn 页面的末尾
- 章节简介或教程中不得包含 Challenges
- 每个 challenge 都使用带 ID 的
####标题
<Deprecated>
用于已弃用的 API。内容应说明改用什么。
页面级弃用
<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>
方法级弃用
### `componentWillMount()` {/*componentwillmount*/}
<Deprecated>
This API has been renamed from `componentWillMount` to [`UNSAFE_componentWillMount`.](#unsafe_componentwillmount)
Run the [`rename-unsafe-lifecycles` codemod](codemod-link) to automatically update.
</Deprecated>
<RSC>
用于仅适用于 React Server Components 的 API。
基本 RSC
<RSC>
`cache` is only for use with [React Server Components](/reference/rsc/server-components).
</RSC>
扩展 RSC(用于 Server Functions)
<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>
<Canary> 和 <CanaryBadge />
用于仅在 Canary 版本中提供的功能。
Canary 包装器(内嵌于简介中)
<Intro>
`<Fragment>` lets you group elements without a wrapper node.
<Canary>Fragments can also accept refs, enabling interaction with underlying DOM nodes.</Canary>
</Intro>
章节标题中的 CanaryBadge
### <CanaryBadge /> FragmentInstance {/*fragmentinstance*/}
属性列表中的 CanaryBadge
* <CanaryBadge /> **optional** `ref`: A ref object from `useRef` or callback function.
注意事项中的 CanaryBadge
* <CanaryBadge /> If you want to pass `ref` to a Fragment, you can't use the `<>...</>` syntax.
<Diagram>
用于直观说明模块依赖关系、渲染树或数据流。
<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>
属性:
name:图表标识符(用于图像文件)height:高度,单位为像素width:宽度,单位为像素alt:图表的无障碍描述
<CodeStep>(谨慎使用)
用于正文中的编号提示框,与代码块注释配合使用。
语法
在代码块中:
```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.
指南
- 每段说明最多使用 2-3 种不同颜色
- 不要高亮每个关键词,只高亮关键概念
- 用于正文中的术语,不要用于整个代码块
- 在同一章节中保持用法一致
✅ 良好用法——高亮关键概念:
React will compare the <CodeStep step={2}>dependencies</CodeStep> with the dependencies you passed...
🚫 避免——过度高亮:
When an <CodeStep step={1}>Activity</CodeStep> boundary is <CodeStep step={2}>hidden</CodeStep> during its <CodeStep step={3}>initial</CodeStep> render...
<ConsoleBlock>
显示控制台输出(错误、警告、日志)。
<ConsoleBlock level="error">
Uncaught Error: Too many re-renders.
</ConsoleBlock>
级别: error、warning、info
按页面类型使用组件
参考页面
如需了解参考页面特有的组件放置规则,请调用 /docs-writer-reference。
关键放置模式:
<RSC>放在页面顶部的<Intro>之前- 页面级弃用时,
<Deprecated>放在<Intro>之后 - 方法级弃用时,
<Deprecated>放在方法标题之后 <Canary>包装器在<Intro>中以内联形式出现<CanaryBadge />出现在标题、属性列表和注意事项中
学习页面
如需了解学习页面的结构和模式,请调用 /docs-writer-learn。
关键使用模式:
- 挑战仅放在标准学习页面的末尾
- 章节简介或教程中不使用挑战
- 使用 DeepDive 展示可选的进阶内容
- 谨慎使用 CodeStep
博客页面
如需了解博客页面的结构和模式,请调用 /docs-writer-blog。
关键使用模式:
- 通常避免使用深度技术组件
- 可使用 Note 和 Pitfall 进行说明
- 优先使用内联说明,而非 DeepDive
其他可用组件
版本/状态: <Experimental>、<ExperimentalBadge />、<RSCBadge />、<NextMajor>、<Wip>
视觉元素: <DiagramGroup>、<Illustration>、<IllustrationBlock>、<CodeDiagram>、<FullWidth>
控制台: <ConsoleBlockMulti>、<ConsoleLogLine>
专用组件: <TerminalBlock>、<BlogCard>、<TeamMember>、<YouTubeIframe>、<ErrorDecoder />、<LearnMore>、<Math>、<MathI>、<LanguageList>
请参阅现有文档,了解这些组件的使用示例。