20 | {message}
21 |
22 | This page doesn’t exist.
17 |18 | If this is a mistake{', '} 19 | 20 | let us know 21 | 22 | {', '} 23 | and we will try to fix it! 24 |
25 |Something went very wrong.
20 |Sorry about that.
21 |22 | If you’d like, please{' '} 23 | 24 | report a bug. 25 | 26 |
27 | in case of RTL languages to avoid like `()console.log` to be rendered as `console.log()`
19 | className={cn(
20 | 'inline text-code text-secondary dark:text-secondary-dark px-1 rounded-md no-underline',
21 | {
22 | 'bg-gray-30 bg-opacity-10 py-px': !isLink,
23 | 'bg-highlight dark:bg-highlight-dark py-0': isLink,
24 | }
25 | )}
26 | {...props}
27 | />
28 | );
29 | }
30 |
31 | export default InlineCode;
32 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "strict": true,
12 | "noImplicitAny": true,
13 | "noImplicitReturns": true,
14 | "noImplicitThis": true,
15 | "strictNullChecks": true,
16 | "forceConsistentCasingInFileNames": true,
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "module": "esnext",
20 | "moduleResolution": "node",
21 | "resolveJsonModule": true,
22 | "isolatedModules": true,
23 | "jsx": "preserve",
24 | "baseUrl": "src",
25 | "incremental": true,
26 | "plugins": [
27 | {
28 | "name": "next"
29 | }
30 | ]
31 | },
32 | "include": [
33 | "next-env.d.ts",
34 | "src/**/*.ts",
35 | "src/**/*.tsx",
36 | ".next/types/**/*.ts"
37 | ],
38 | "exclude": [
39 | "node_modules"
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/src/content/reference/react-dom/static/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Static React DOM APIs
3 | ---
4 |
5 |
6 |
7 | `react-dom/static` API 允许你为 React 组件生成静态 HTML。与流式 API 相比,它们的功能有限。[框架](/learn/start-a-new-react-project#production-grade-react-frameworks) 可能会调用它们。你的大多数组件不需要导入或使用它们。
8 |
9 |
10 |
11 | ---
12 |
13 | ## Web 流的静态 API {/*static-apis-for-web-streams*/}
14 |
15 | 这些方法仅在支持 [Web 流](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) 的环境中可用,包括浏览器、Deno 和一些现代的边缘运行时环境:
16 |
17 | * [`prerender`](/reference/react-dom/static/prerender) 使用 [可读的 Web 流](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) 将 React 树渲染为静态 HTML。
18 |
19 |
20 | ---
21 |
22 | ## Node.js 流的静态 API {/*static-apis-for-nodejs-streams*/}
23 |
24 | 这些方法仅在支持 [Node.js 流](https://nodejs.org/api/stream.html) 的环境中可用:
25 |
26 | * [`prerenderToNodeStream`](/reference/react-dom/static/prerenderToNodeStream) 使用 [Node.js 流](https://nodejs.org/api/stream.html) 将 React 树渲染为静态 HTML。
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.github/workflows/site_lint.yml:
--------------------------------------------------------------------------------
1 | name: Site Lint / Heading ID check
2 |
3 | on:
4 | push:
5 | branches:
6 | - main # change this if your default branch is named differently
7 | pull_request:
8 | types: [opened, synchronize, reopened]
9 |
10 | jobs:
11 | lint:
12 | runs-on: ubuntu-latest
13 |
14 | name: Lint on node 20.x and ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v4
18 | - name: Use Node.js 20.x
19 | uses: actions/setup-node@v4
20 | with:
21 | node-version: 20.x
22 | cache: yarn
23 | cache-dependency-path: yarn.lock
24 |
25 | - name: Restore cached node_modules
26 | uses: actions/cache@v4
27 | with:
28 | path: "**/node_modules"
29 | key: node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
30 |
31 | - name: Install deps
32 | run: yarn install --frozen-lockfile
33 |
34 | - name: Lint codebase
35 | run: yarn ci-check
36 |
--------------------------------------------------------------------------------
/src/components/MDX/Sandpack/OpenInTypeScriptPlayground.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {IconNewPage} from '../../Icon/IconNewPage';
6 |
7 | export const OpenInTypeScriptPlaygroundButton = (props: {content: string}) => {
8 | const contentWithReactImport = `import * as React from 'react';\n\n${props.content}`;
9 | return (
10 |
18 |
23 | TypeScript Playground
24 |
25 | );
26 | };
27 |
--------------------------------------------------------------------------------
/src/components/Icon/IconGitHub.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 | import type {SVGProps} from 'react';
7 |
8 | export const IconGitHub = memo>(function IconGitHub(
9 | props
10 | ) {
11 | return (
12 |
21 | );
22 | });
23 |
--------------------------------------------------------------------------------
/src/components/Icon/IconBsky.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 | import type {SVGProps} from 'react';
7 |
8 | export const IconBsky = memo>(function IconBsky(props) {
9 | return (
10 |
22 | );
23 | });
24 |
--------------------------------------------------------------------------------
/plugins/markdownToHtml.js:
--------------------------------------------------------------------------------
1 | const remark = require('remark');
2 | const externalLinks = require('remark-external-links'); // Add _target and rel to external links
3 | const customHeaders = require('./remark-header-custom-ids'); // Custom header id's for i18n
4 | const images = require('remark-images'); // Improved image syntax
5 | const unrwapImages = require('remark-unwrap-images'); // Removes wrapper around images
6 | const smartyPants = require('./remark-smartypants'); // Cleans up typography
7 | const html = require('remark-html');
8 |
9 | module.exports = {
10 | remarkPlugins: [
11 | externalLinks,
12 | customHeaders,
13 | images,
14 | unrwapImages,
15 | smartyPants,
16 | ],
17 | markdownToHtml,
18 | };
19 |
20 | async function markdownToHtml(markdown) {
21 | const result = await remark()
22 | .use(externalLinks)
23 | .use(customHeaders)
24 | .use(images)
25 | .use(unrwapImages)
26 | .use(smartyPants)
27 | .use(html)
28 | .process(markdown);
29 | return result.toString();
30 | }
31 |
--------------------------------------------------------------------------------
/src/utils/toCommaSeparatedList.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import * as React from 'react';
6 |
7 | const addString = (list: React.ReactNode[], string: string) =>
8 | list.push({string});
9 |
10 | function toCommaSeparatedList- (
11 | array: Item[],
12 | renderCallback: (item: Item, index: number) => React.ReactNode
13 | ): React.ReactNode[] {
14 | if (array.length <= 1) {
15 | return array.map(renderCallback);
16 | }
17 |
18 | const list: React.ReactNode[] = [];
19 |
20 | array.forEach((item, index) => {
21 | if (index === array.length - 1) {
22 | addString(list, array.length === 2 ? ' and ' : ', and ');
23 | list.push(renderCallback(item, index));
24 | } else if (index > 0) {
25 | addString(list, ', ');
26 | list.push(renderCallback(item, index));
27 | } else {
28 | list.push(renderCallback(item, index));
29 | }
30 | });
31 |
32 | return list;
33 | }
34 |
35 | export default toCommaSeparatedList;
36 |
--------------------------------------------------------------------------------
/.github/workflows/label_core_team_prs.yml:
--------------------------------------------------------------------------------
1 | name: Label Core Team PRs
2 |
3 | on:
4 | pull_request_target:
5 |
6 | env:
7 | TZ: /usr/share/zoneinfo/America/Los_Angeles
8 | # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
9 | SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
10 |
11 | jobs:
12 | check_maintainer:
13 | uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
14 | with:
15 | actor: ${{ github.event.pull_request.user.login }}
16 | is_remote: true
17 |
18 | label:
19 | if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
20 | runs-on: ubuntu-latest
21 | needs: check_maintainer
22 | steps:
23 | - name: Label PR as React Core Team
24 | uses: actions/github-script@v7
25 | with:
26 | script: |
27 | github.rest.issues.addLabels({
28 | owner: context.repo.owner,
29 | repo: context.repo.repo,
30 | issue_number: ${{ github.event.number }},
31 | labels: ['React Core Team']
32 | });
33 |
--------------------------------------------------------------------------------
/src/content/reference/react-dom/hooks/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Built-in React DOM Hooks"
3 | ---
4 |
5 |
6 |
7 | `react-dom` 包含的 Hook 仅支持 web 应用程序,即在浏览器 DOM 环境中运行的应用程序。这些 Hook 不支持非浏览器环境,如 iOS、Android 或 Windows 应用程序。如果正在寻找在 web 浏览器以及其他环境中支持的 Hook,请参阅 [React Hooks 页面](/reference/react)。该页面列出了 `react-dom` 包中的所有 Hook。
8 |
9 |
10 |
11 | ---
12 |
13 | ## Form Hooks {/*form-hooks*/}
14 |
15 | **Form** 允许创建用于提交信息的交互式控件。要在组件中管理表单,请使用以下其中一个 Hook:
16 |
17 | * [`useFormStatus`](/reference/react-dom/hooks/useFormStatus) 允许根据表单的状态更新用户界面。
18 |
19 | ```js
20 | function Form({ action }) {
21 | async function increment(n) {
22 | return n + 1;
23 | }
24 | const [count, incrementFormAction] = useActionState(increment, 0);
25 | return (
26 |
30 | );
31 | }
32 |
33 | function Button() {
34 | const { pending } = useFormStatus();
35 | return (
36 |
39 | );
40 | }
41 | ```
42 |
--------------------------------------------------------------------------------
/src/components/MDX/MDXComponents.module.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | /* Stop purging. */
6 | .markdown p {
7 | @apply mb-4 leading-7 whitespace-pre-wrap text-gray-70;
8 | }
9 |
10 | .markdown ol {
11 | @apply mb-4 ms-8 list-decimal;
12 | }
13 |
14 | .markdown ul {
15 | @apply mb-4 ms-8 list-disc;
16 | }
17 |
18 | .markdown h1 {
19 | @apply mb-6 text-4xl font-extrabold tracking-tight;
20 | }
21 |
22 | .markdown h2 {
23 | @apply mt-12 mb-4 text-3xl font-extrabold tracking-tight;
24 | }
25 | .markdown h3 {
26 | @apply mt-8 mb-3 text-2xl font-extrabold tracking-tight;
27 | }
28 | .markdown h4 {
29 | @apply mt-8 mb-3 text-xl font-extrabold tracking-tight;
30 | }
31 |
32 | .markdown code {
33 | @apply text-gray-70 bg-card dark:bg-card-dark p-1 rounded-lg no-underline;
34 | font-size: 90%;
35 | }
36 |
37 | .markdown li {
38 | @apply mb-2;
39 | }
40 |
41 | .markdown a {
42 | @apply inline text-link dark:text-link-dark break-normal border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal;
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/Icon/IconTerminal.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 |
7 | export const IconTerminal = memo(
8 | function IconTerminal({className}) {
9 | return (
10 |
22 | );
23 | }
24 | );
25 |
--------------------------------------------------------------------------------
/src/components/MDX/PackageImport.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {Children} from 'react';
6 | import * as React from 'react';
7 | import CodeBlock from './CodeBlock';
8 |
9 | interface PackageImportProps {
10 | children: React.ReactNode;
11 | }
12 |
13 | export function PackageImport({children}: PackageImportProps) {
14 | const terminal = Children.toArray(children).filter((child: any) => {
15 | return child.type?.mdxName !== 'pre';
16 | });
17 | const code = Children.toArray(children).map((child: any, i: number) => {
18 | if (child.type?.mdxName === 'pre') {
19 | return (
20 |
27 | );
28 | } else {
29 | return null;
30 | }
31 | });
32 | return (
33 |
34 | {terminal}
35 | {code}
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/src/components/Icon/IconArrow.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 | import cn from 'classnames';
7 | import type {SVGProps} from 'react';
8 |
9 | export const IconArrow = memo<
10 | SVGProps & {
11 | /**
12 | * The direction the arrow should point.
13 | * `start` and `end` are relative to the current locale.
14 | * for example, in LTR, `start` is left and `end` is right.
15 | */
16 | displayDirection: 'start' | 'end' | 'right' | 'left' | 'up' | 'down';
17 | }
18 | >(function IconArrow({displayDirection, className, ...rest}) {
19 | return (
20 |
34 | );
35 | });
36 |
--------------------------------------------------------------------------------
/src/components/MDX/Sandpack/Themes.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import tailwindConfig from '../../../../tailwind.config';
6 |
7 | export const CustomTheme = {
8 | colors: {
9 | accent: 'inherit',
10 | base: 'inherit',
11 | clickable: 'inherit',
12 | disabled: 'inherit',
13 | error: 'inherit',
14 | errorSurface: 'inherit',
15 | hover: 'inherit',
16 | surface1: 'inherit',
17 | surface2: 'inherit',
18 | surface3: 'inherit',
19 | warning: 'inherit',
20 | warningSurface: 'inherit',
21 | },
22 | syntax: {
23 | plain: 'inherit',
24 | comment: 'inherit',
25 | keyword: 'inherit',
26 | tag: 'inherit',
27 | punctuation: 'inherit',
28 | definition: 'inherit',
29 | property: 'inherit',
30 | static: 'inherit',
31 | string: 'inherit',
32 | },
33 | font: {
34 | body: tailwindConfig.theme.extend.fontFamily.text
35 | .join(', ')
36 | .replace(/"/gm, ''),
37 | mono: tailwindConfig.theme.extend.fontFamily.mono
38 | .join(', ')
39 | .replace(/"/gm, ''),
40 | size: tailwindConfig.theme.extend.fontSize.code,
41 | lineHeight: '24px',
42 | },
43 | };
44 |
--------------------------------------------------------------------------------
/src/components/Icon/IconSolution.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 | import cn from 'classnames';
7 |
8 | export const IconSolution = memo(
9 | function IconSolution({className}) {
10 | return (
11 |
22 | );
23 | }
24 | );
25 |
--------------------------------------------------------------------------------
/src/components/MDX/YouWillLearnCard.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import * as React from 'react';
6 | import ButtonLink from 'components/ButtonLink';
7 | import {IconNavArrow} from 'components/Icon/IconNavArrow';
8 |
9 | interface YouWillLearnCardProps {
10 | title: string;
11 | path: string;
12 | children: React.ReactNode;
13 | }
14 |
15 | function YouWillLearnCard({title, path, children}: YouWillLearnCardProps) {
16 | return (
17 |
18 |
19 |
20 | {title}
21 |
22 | {children}
23 |
24 |
25 |
31 | 阅读更多
32 |
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | export default YouWillLearnCard;
40 |
--------------------------------------------------------------------------------
/.github/workflows/discord_notify.yml:
--------------------------------------------------------------------------------
1 | name: Discord Notify
2 |
3 | on:
4 | pull_request_target:
5 | types: [labeled]
6 |
7 | jobs:
8 | check_maintainer:
9 | uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
10 | with:
11 | actor: ${{ github.event.pull_request.user.login }}
12 | is_remote: true
13 |
14 | notify:
15 | if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
16 | needs: check_maintainer
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Discord Webhook Action
20 | uses: tsickert/discord-webhook@v6.0.0
21 | with:
22 | webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
23 | embed-author-name: ${{ github.event.pull_request.user.login }}
24 | embed-author-url: ${{ github.event.pull_request.user.html_url }}
25 | embed-author-icon-url: ${{ github.event.pull_request.user.avatar_url }}
26 | embed-title: '#${{ github.event.number }} (+${{github.event.pull_request.additions}} -${{github.event.pull_request.deletions}}): ${{ github.event.pull_request.title }}'
27 | embed-description: ${{ github.event.pull_request.body }}
28 | embed-url: ${{ github.event.pull_request.html_url }}
29 |
--------------------------------------------------------------------------------
/src/content/community/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: React Community
3 | ---
4 |
5 |
6 |
7 | React 拥有数百万开发者的社区。本章节将为你列出一些与 React 相关的社区,你也可以成为其中的一员;本章节中的其他页面将为你提供更多在线与面对面的学习资料。
8 |
9 |
10 |
11 | ## 行为准则 {/*code-of-conduct*/}
12 |
13 | 在参与 React 社区前,[请阅读我们的行为准则](https://github.com/facebook/react/blob/main/CODE_OF_CONDUCT.md)。我们制订了 [贡献者公约](https://www.contributor-covenant.org/),我们希望所有社区成员都能遵守其中的准则。
14 |
15 | ## Stack Overflow {/*stack-overflow*/}
16 |
17 | Stack Overflow 是非常受欢迎的论坛,在论坛中,你可以提出代码层面的问题,甚至是你工作中的疑难杂症。提问前,请先阅读标有 **reactjs** 的 [已有问题](https://stackoverflow.com/questions/tagged/reactjs),如未找到你需要的答案,[再自行提问](https://stackoverflow.com/questions/ask?tags=reactjs)!
18 |
19 | ## 热门讨论区 {/*popular-discussion-forums*/}
20 |
21 | 许多论坛是讨论最佳实践、应用架构以及 React 新特性的好地方。但如果你想讨论的是代码级问题,通常 Stack Overflow 会更合适。
22 |
23 | 每个社区都由成千上万的 React 开发者组成。
24 |
25 | * [DEV's React community](https://dev.to/t/react)
26 | * [Hashnode's React community](https://hashnode.com/n/reactjs)
27 | * [Reactiflux online chat](https://discord.gg/reactiflux)
28 | * [Reddit's React community](https://www.reddit.com/r/reactjs/)
29 |
30 | ## 新闻 {/*news*/}
31 |
32 | 关于 React 的最新消息,请在 Twitter 上关注 [**@reactjs**](https://twitter.com/reactjs),同时关注本站中的 [React 的官方博客](/blog/)。
33 |
--------------------------------------------------------------------------------
/src/components/Tag.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import cn from 'classnames';
6 | import type {RouteTag} from './Layout/getRouteMeta';
7 |
8 | const variantMap = {
9 | foundation: {
10 | name: '基础',
11 | classes: 'bg-yellow-50 text-white',
12 | },
13 | intermediate: {
14 | name: '中级',
15 | classes: 'bg-purple-40 text-white',
16 | },
17 | advanced: {
18 | name: '高级',
19 | classes: 'bg-green-40 text-white',
20 | },
21 | experimental: {
22 | name: '实验性的',
23 | classes: 'bg-ui-orange text-white',
24 | },
25 | deprecated: {
26 | name: '弃用',
27 | classes: 'bg-red-40 text-white',
28 | },
29 | };
30 |
31 | interface TagProps {
32 | variant: RouteTag;
33 | text?: string;
34 | className?: string;
35 | }
36 |
37 | function Tag({text, variant, className}: TagProps) {
38 | const {name, classes} = variantMap[variant];
39 | return (
40 |
41 |
46 | {text || name}
47 |
48 |
49 | );
50 | }
51 |
52 | export default Tag;
53 |
--------------------------------------------------------------------------------
/src/sidebarCommunity.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "社区",
3 | "path": "/community",
4 | "routes": [
5 | {
6 | "hasSectionHeader": true,
7 | "sectionHeader": "参与贡献"
8 | },
9 | {
10 | "title": "社区",
11 | "path": "/community",
12 | "skipBreadcrumb": true,
13 | "routes": [
14 | {
15 | "title": "React Conf",
16 | "path": "/community/conferences"
17 | },
18 | {
19 | "title": "React 见面会",
20 | "path": "/community/meetups"
21 | },
22 | {
23 | "title": "React 视频",
24 | "path": "/community/videos"
25 | },
26 | {
27 | "title": "React 团队",
28 | "path": "/community/team"
29 | },
30 | {
31 | "title": "文档贡献者",
32 | "path": "/community/docs-contributors"
33 | },
34 | {
35 | "title": "Translations",
36 | "path": "/community/translations"
37 | },
38 | {
39 | "title": "Acknowledgements",
40 | "path": "/community/acknowledgements"
41 | },
42 | {
43 | "title": "版本策略",
44 | "path": "/community/versioning-policy"
45 | }
46 | ]
47 | }
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/src/content/blog/2020/12/21/data-fetching-with-react-server-components.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "介绍零打包大小的 React 服务器组件"
3 | author: Dan Abramov, Lauren Tan, Joseph Savona, and Sebastian Markbage
4 | date: 2020/12/21
5 | description: 2020 年是漫长的一年。随着它的结束,我们想在节日里分享一份特别的更新,介绍我们对零打包大小的 React 服务器组件的研究。
6 | ---
7 |
8 | 2020 年 12 月 21 日 [Dan Abramov](https://bsky.app/profile/danabra.mov)、[Lauren Tan](https://twitter.com/potetotes)、[Joseph Savona](https://twitter.com/en_JS) 与 [Sebastian Markbåge](https://twitter.com/sebmarkbage)
9 |
10 | ---
11 |
12 |
13 |
14 | 2020 年是漫长的一年。随着它的结束,我们想在节日里分享一份特别的更新,介绍我们对零打包大小的 **React 服务器组件** 的研究。
15 |
16 |
17 |
18 | ---
19 |
20 | 为了介绍 React 服务器组件,我们准备了一次演讲和演示。如果你愿意,在假期期间或新年工作重新开始后查看它们。
21 |
22 |
23 |
24 | **React 服务器组件仍处于研究和开发阶段**。我们将以透明的精神分享这项工作,并希望从 React 社区获得初步反馈。这个过程需要很多时间,所以 **你现在不必急着赶上进展**!
25 |
26 | 如果你想了解它们,我们建议按照以下顺序进行查看:
27 |
28 | 1. **观看演讲** 以了解 React 服务器组件并观看演示。
29 |
30 | 2. **[克隆演示](http://github.com/reactjs/server-components-demo)** 并在你的计算机上尝试使用 React 服务器组件。
31 |
32 | 3. **[阅读 RFC(文末有FAQ)](https://github.com/reactjs/rfcs/pull/188)** 以深入了解技术细节并提供反馈意见。
33 |
34 | 我们非常期待你对 RFC 的反馈或者通过 [@reactjs](https://twitter.com/reactjs) 的 Twitter 账号回复我们。祝你度过愉快的假期,保重,明年再见!
35 |
--------------------------------------------------------------------------------
/src/components/MDX/CodeBlock/index.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import * as React from 'react';
6 | import cn from 'classnames';
7 | import {lazy, memo, Suspense} from 'react';
8 | const CodeBlock = lazy(() => import('./CodeBlock'));
9 |
10 | export default memo(function CodeBlockWrapper(props: {
11 | children: React.ReactNode & {
12 | props: {
13 | className: string;
14 | children: string;
15 | meta?: string;
16 | };
17 | };
18 | isFromPackageImport: boolean;
19 | noMargin?: boolean;
20 | noMarkers?: boolean;
21 | }): any {
22 | const {children, isFromPackageImport} = props;
23 | return (
24 |
33 |
34 | {children}
35 |
36 |
37 | }>
38 |
39 |
40 | );
41 | });
42 |
--------------------------------------------------------------------------------
/src/content/warnings/react-test-renderer.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: react-test-renderer Deprecation Warnings
3 | ---
4 |
5 | TODO: Update this for 19?
6 |
7 | ## ReactTestRenderer.create() warning {/*reacttestrenderercreate-warning*/}
8 |
9 | react-test-renderer is deprecated. A warning will fire whenever calling ReactTestRenderer.create() or ReactShallowRender.render(). The react-test-renderer package will remain available on NPM but will not be maintained and may break with new React features or changes to React's internals.
10 |
11 | The React Team recommends migrating your tests to [@testing-library/react](https://testing-library.com/docs/react-testing-library/intro/) or [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/docs/start/intro) for a modern and well supported testing experience.
12 |
13 |
14 | ## new ShallowRenderer() warning {/*new-shallowrenderer-warning*/}
15 |
16 | The react-test-renderer package no longer exports a shallow renderer at `react-test-renderer/shallow`. This was simply a repackaging of a previously extracted separate package: `react-shallow-renderer`. Therefore you can continue using the shallow renderer in the same way by installing it directly. See [Github](https://github.com/enzymejs/react-shallow-renderer) / [NPM](https://www.npmjs.com/package/react-shallow-renderer).
17 |
--------------------------------------------------------------------------------
/src/components/Icon/IconWarning.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 |
7 | export const IconWarning = memo(
8 | function IconWarning({className}) {
9 | return (
10 |
25 | );
26 | }
27 | );
28 |
--------------------------------------------------------------------------------
/public/images/home/conf2021/cover.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/src/content/reference/react-dom/server/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server React DOM API
3 | ---
4 |
5 |
6 |
7 | `react-dom/server` API 允许你通过服务端渲染将 React 组件渲染为 HTML。这些 API 仅在服务器应用程序顶层调用,以生成初始 HTML。有的 [框架](/learn/start-a-new-react-project#production-grade-react-frameworks) 可能会为你调用相关 API。大多数组件不需要导入或使用这些 API。
8 |
9 |
10 |
11 | ---
12 |
13 | ## Node.js 流服务器 API {/*server-apis-for-nodejs-streams*/}
14 |
15 | 以下方法仅在具有 [Node.js 流](https://nodejs.org/api/stream.html) 的环境中可用:
16 |
17 | * [`renderToPipeableStream`](/reference/react-dom/server/renderToPipeableStream) 将 React 树渲染为可传输的 [Node.js 流](https://nodejs.org/api/stream.html)。
18 |
19 | ---
20 |
21 | ## Web 流服务器 API {/*server-apis-for-web-streams*/}
22 |
23 | 以下方法仅在具有 [web 流](https://developer.mozilla.org/zh-CN/docs/Web/API/Streams_API) 的环境中可用,包括浏览器、Deno,以及一些现代 edge 运行时:
24 |
25 | + [`renderToReadableStream`](/reference/react-dom/server/renderToReadableStream) 将 React 树渲染为 [可读的 web 流](https://developer.mozilla.org/zh-CN/docs/Web/API/ReadableStream)。
26 |
27 | ---
28 |
29 | ## 过时的非流式环境 API {/*legacy-server-apis-for-non-streaming-environments*/}
30 |
31 | 以下方法可以在非流式环境中使用:
32 |
33 | * [`renderToString`](/reference/react-dom/server/renderToString) 将 React 树渲染为字符串。
34 | * [`renderToStaticMarkup`](/reference/react-dom/server/renderToStaticMarkup) 将非交互式 React 树渲染为字符串。
35 |
36 | 相比于流式 API,这些 API 在功能上有些限制。
37 |
--------------------------------------------------------------------------------
/src/hooks/usePendingRoute.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {useRouter} from 'next/router';
6 | import {useState, useRef, useEffect} from 'react';
7 |
8 | const usePendingRoute = () => {
9 | const {events} = useRouter();
10 | const [pendingRoute, setPendingRoute] = useState(null);
11 | const currentRoute = useRef(null);
12 | useEffect(() => {
13 | let routeTransitionTimer: any = null;
14 |
15 | const handleRouteChangeStart = (url: string) => {
16 | clearTimeout(routeTransitionTimer);
17 | routeTransitionTimer = setTimeout(() => {
18 | if (currentRoute.current !== url) {
19 | currentRoute.current = url;
20 | setPendingRoute(url);
21 | }
22 | }, 100);
23 | };
24 | const handleRouteChangeComplete = () => {
25 | setPendingRoute(null);
26 | clearTimeout(routeTransitionTimer);
27 | };
28 | events.on('routeChangeStart', handleRouteChangeStart);
29 | events.on('routeChangeComplete', handleRouteChangeComplete);
30 |
31 | return () => {
32 | events.off('routeChangeStart', handleRouteChangeStart);
33 | events.off('routeChangeComplete', handleRouteChangeComplete);
34 | clearTimeout(routeTransitionTimer);
35 | };
36 | }, [events]);
37 |
38 | return pendingRoute;
39 | };
40 |
41 | export default usePendingRoute;
42 |
--------------------------------------------------------------------------------
/src/content/learn/setup.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Setup
3 | ---
4 |
5 |
6 | React integrates with tools like editors, TypeScript, browser extensions, and compliers. This section will help you get your environment set up.
7 |
8 |
9 |
10 | ## Editor Setup {/*editor-setup*/}
11 |
12 | See our [recommended editors](/learn/editor-setup) and learn how to set them up to work with React.
13 |
14 | ## Using TypeScript {/*using-typescript*/}
15 |
16 | TypeScript is a popular way to add type definitions to JavaScript codebases. [Learn how to integrate TypeScript into your React projects](/learn/typescript).
17 |
18 | ## React Developer Tools {/*react-developer-tools*/}
19 |
20 | React Developer Tools is a browser extension that can inspect React components, edit props and state, and identify performance problems. Learn how to install it [here](learn/react-developer-tools).
21 |
22 | ## React Compiler {/*react-compiler*/}
23 |
24 | React Compiler is a tool that automatically optimizes your React app. [Learn more](/learn/react-compiler).
25 |
26 | ## Start a React Project from scratch {/*start-a-react-project-from-scratch*/}
27 |
28 | If you want to build your own framework, you can [start a React project from scratch](/learn/start-a-react-project-from-scratch).
29 |
30 | ## Next steps {/*next-steps*/}
31 |
32 | Head to the [Quick Start](/learn) guide for a tour of the most important React concepts you will encounter every day.
33 |
--------------------------------------------------------------------------------
/src/components/MDX/Sandpack/template.ts:
--------------------------------------------------------------------------------
1 | export const template = {
2 | '/src/index.js': {
3 | hidden: true,
4 | code: `import React, { StrictMode } from "react";
5 | import { createRoot } from "react-dom/client";
6 | import "./styles.css";
7 |
8 | import App from "./App";
9 |
10 | const root = createRoot(document.getElementById("root"));
11 | root.render(
12 |
13 |
14 |
15 | );`,
16 | },
17 | '/package.json': {
18 | hidden: true,
19 | code: JSON.stringify(
20 | {
21 | name: 'react.dev',
22 | version: '0.0.0',
23 | main: '/src/index.js',
24 | scripts: {
25 | start: 'react-scripts start',
26 | build: 'react-scripts build',
27 | test: 'react-scripts test --env=jsdom',
28 | eject: 'react-scripts eject',
29 | },
30 | dependencies: {
31 | react: '19.0.0-rc-3edc000d-20240926',
32 | 'react-dom': '19.0.0-rc-3edc000d-20240926',
33 | 'react-scripts': '^5.0.0',
34 | },
35 | },
36 | null,
37 | 2
38 | ),
39 | },
40 | '/public/index.html': {
41 | hidden: true,
42 | code: `
43 |
44 |
45 |
46 |
47 | Document
48 |
49 |
50 |
51 |
52 | `,
53 | },
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/MDX/CodeDiagram.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {Children} from 'react';
6 | import * as React from 'react';
7 | import CodeBlock from './CodeBlock';
8 |
9 | interface CodeDiagramProps {
10 | children: React.ReactNode;
11 | flip?: boolean;
12 | }
13 |
14 | export function CodeDiagram({children, flip = false}: CodeDiagramProps) {
15 | const illustration = Children.toArray(children).filter((child: any) => {
16 | return child.type === 'img';
17 | });
18 | const content = Children.toArray(children).map((child: any) => {
19 | if (child.type?.mdxName === 'pre') {
20 | return (
21 |
27 | );
28 | } else if (child.type === 'img') {
29 | return null;
30 | } else {
31 | return child;
32 | }
33 | });
34 | if (flip) {
35 | return (
36 |
37 | {illustration}
38 | {content}
39 |
40 | );
41 | }
42 | return (
43 |
44 | {content}
45 | {illustration}
46 |
47 | );
48 | }
49 |
--------------------------------------------------------------------------------
/public/html/single-file-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello World
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
22 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/src/components/Button.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import * as React from 'react';
6 | import cn from 'classnames';
7 |
8 | interface ButtonProps {
9 | children: React.ReactNode;
10 | onClick?: (event: React.MouseEvent) => void;
11 | active?: boolean;
12 | className?: string;
13 | style?: Record;
14 | }
15 |
16 | export function Button({
17 | children,
18 | onClick,
19 | active = false,
20 | className,
21 | style,
22 | }: ButtonProps) {
23 | return (
24 |
43 | );
44 | }
45 |
46 | export default Button;
47 |
--------------------------------------------------------------------------------
/src/components/Icon/IconArrowSmall.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 | import cn from 'classnames';
7 | import type {SVGProps} from 'react';
8 |
9 | export const IconArrowSmall = memo<
10 | SVGProps & {
11 | /**
12 | * The direction the arrow should point.
13 | * `start` and `end` are relative to the current locale.
14 | * for example, in LTR, `start` is left and `end` is right.
15 | */
16 | displayDirection: 'start' | 'end' | 'right' | 'left' | 'up' | 'down';
17 | }
18 | >(function IconArrowSmall({displayDirection, className, ...rest}) {
19 | const classes = cn(className, {
20 | 'rotate-180': displayDirection === 'left',
21 | 'rotate-180 rtl:rotate-0': displayDirection === 'start',
22 | 'rotate-90': displayDirection === 'down',
23 | });
24 | return (
25 |
37 | );
38 | });
39 |
--------------------------------------------------------------------------------
/src/components/MDX/Sandpack/useSandpackLint.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | // @ts-nocheck
6 |
7 | import {useState, useEffect} from 'react';
8 | import type {EditorView} from '@codemirror/view';
9 |
10 | export type LintDiagnostic = {
11 | line: number;
12 | column: number;
13 | severity: 'warning' | 'error';
14 | message: string;
15 | }[];
16 |
17 | export const useSandpackLint = () => {
18 | const [lintErrors, setLintErrors] = useState([]);
19 | const [lintExtensions, setLintExtensions] = useState([]);
20 | useEffect(() => {
21 | const loadLinter = async () => {
22 | const {linter} = await import('@codemirror/lint');
23 | const onLint = linter(async (props: EditorView) => {
24 | // This is intentionally delayed until CodeMirror calls it
25 | // so that we don't take away bandwidth from things loading early.
26 | const {runESLint} = await import('./runESLint');
27 | const editorState = props.state.doc;
28 | let {errors, codeMirrorErrors} = runESLint(editorState);
29 | // Ignore parsing or internal linter errors.
30 | const isReactRuleError = (error: any) => error.ruleId != null;
31 | setLintErrors(errors.filter(isReactRuleError));
32 | return codeMirrorErrors.filter(isReactRuleError);
33 | });
34 | setLintExtensions([onLint]);
35 | };
36 |
37 | loadLinter();
38 | }, []);
39 | return {lintErrors, lintExtensions};
40 | };
41 |
--------------------------------------------------------------------------------
/src/content/community/translations.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Translations
3 | ---
4 |
5 |
6 |
7 | React docs are translated by the global community into many languages all over the world.
8 |
9 |
10 |
11 | ## Source site {/*main-site*/}
12 |
13 | All translations are provided from the canonical source docs:
14 |
15 | - [English](https://react.dev/) — [Contribute](https://github.com/reactjs/react.dev/)
16 |
17 | ## Full translations {/*full-translations*/}
18 |
19 | {/* If you are a language maintainer and want to add your language here, finish the "Core" translations and edit `deployedTranslations` under `src/utils`. */}
20 |
21 |
22 |
23 | ## In-progress translations {/*in-progress-translations*/}
24 |
25 | For the progress of each translation, see: [Is React Translated Yet?](https://translations.react.dev/)
26 |
27 |
28 |
29 | ## How to contribute {/*how-to-contribute*/}
30 |
31 | You can contribute to the translation efforts!
32 |
33 | The community conducts the translation work for the React docs on each language-specific fork of react.dev. Typical translation work involves directly translating a Markdown file and creating a pull request. Click the "contribute" link above to the GitHub repository for your language, and follow the instructions there to help with the translation effort.
34 |
35 | If you want to start a new translation for your language, visit: [translations.react.dev](https://github.com/reactjs/translations.react.dev)
--------------------------------------------------------------------------------
/src/components/Icon/IconNote.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {memo} from 'react';
6 |
7 | export const IconNote = memo(function IconNote({
8 | className,
9 | }) {
10 | return (
11 |
40 | );
41 | });
42 |
--------------------------------------------------------------------------------
/src/content/reference/react/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: React 参考总览
3 | ---
4 |
5 |
6 |
7 | 本部分提供了使用 React 的详细参考文档。如果需要了解 React,请访问 [教程](/learn) 部分。
8 |
9 |
10 |
11 | React 参考文档分为以下内容:
12 |
13 | ## React {/*react*/}
14 |
15 | 编程式 React 功能:
16 |
17 | * [Hook](/reference/react/hooks) —— 在组件中使用不同的 React 特性。
18 | * [组件](/reference/react/components) —— 可以在 JSX 中使用的内置组件。
19 | * [API](/reference/react/apis) —— 用于定义组件的有用 API。
20 | * [指示符](/reference/rsc/directives) —— 为与 React 服务器组件兼容的捆绑器提供指示。
21 |
22 | ## React DOM {/*react-dom*/}
23 |
24 | React-dom 仅支持在 web 应用程序中使用(在浏览器 DOM 环境中运行)。本节分为以下部分:
25 |
26 | * [Hook](/reference/react-dom/hooks) —— 适用于在浏览器 DOM 环境中运行的 web 应用程序的 Hook。
27 | * [组件](/reference/react-dom/components) —— React 支持所有内置的 HTML 和 SVG 组件。
28 | * [API](/reference/react-dom) —— `react-dom` 包含仅在 web 应用程序中支持的方法。
29 | * [客户端 API](/reference/react-dom/client) —— `react-dom/client` API 允许在客户端(浏览器中)渲染 React 组件。
30 | * [服务端 API](/reference/react-dom/server) —— `react-dom/server` API 允许在服务器端将 React 组件渲染为 HTML。
31 |
32 |
33 | ## Rules of React {/*rules-of-react*/}
34 |
35 | React 有一套表达模式的俗语与规则,它们以一种易于理解并能帮助实现高质量应用程序的方式表达出来:
36 |
37 | * [组件与 Hook 必须是纯粹的](/reference/rules/components-and-hooks-must-be-pure) —— 组件与 Hook 的纯粹代码更易于理解、调试,并允许 React 自动优化组件与 Hook。
38 | * [React 调用组件与 Hook](/reference/rules/react-calls-components-and-hooks) —— React 负责在必要时渲染组件与 Hook,以优化用户体验。
39 | * [Hook 规则](/reference/rules/rules-of-hooks) —— Hook 使用 JavaScript 函数定义,但它们代表一种特殊类型的可重用 UI 逻辑,对它们可以被调用的位置有限制。
40 |
41 | ## 过时的 API {/*legacy-apis*/}
42 |
43 | * [过时的 API](/reference/react/legacy) —— 从 react 包中导出,但不建议在新编写的代码中使用。
44 |
--------------------------------------------------------------------------------
/src/components/ButtonLink.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import cn from 'classnames';
6 | import NextLink from 'next/link';
7 |
8 | interface ButtonLinkProps {
9 | size?: 'md' | 'lg';
10 | type?: 'primary' | 'secondary';
11 | label?: string;
12 | target?: '_self' | '_blank';
13 | }
14 |
15 | function ButtonLink({
16 | href,
17 | className,
18 | children,
19 | type = 'primary',
20 | size = 'md',
21 | label,
22 | target = '_self',
23 | ...props
24 | }: React.AnchorHTMLAttributes & ButtonLinkProps) {
25 | const classes = cn(
26 | className,
27 | 'active:scale-[.98] transition-transform inline-flex font-bold items-center outline-none focus:outline-none focus-visible:outline focus-visible:outline-link focus:outline-offset-2 focus-visible:dark:focus:outline-link-dark leading-snug',
28 | {
29 | 'bg-link text-white dark:bg-brand-dark dark:text-secondary hover:bg-opacity-80':
30 | type === 'primary',
31 | 'text-primary dark:text-primary-dark shadow-secondary-button-stroke dark:shadow-secondary-button-stroke-dark hover:bg-gray-40/5 active:bg-gray-40/10 hover:dark:bg-gray-60/5 active:dark:bg-gray-60/10':
32 | type === 'secondary',
33 | 'text-lg py-3 rounded-full px-4 sm:px-6': size === 'lg',
34 | 'text-base rounded-full px-4 py-2': size === 'md',
35 | }
36 | );
37 | return (
38 |
44 | {children}
45 |
46 | );
47 | }
48 |
49 | export default ButtonLink;
50 |
--------------------------------------------------------------------------------
/src/components/SocialBanner.tsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | *
4 | */
5 |
6 | import {useRef, useEffect} from 'react';
7 | import cn from 'classnames';
8 | import {ExternalLink} from './ExternalLink';
9 |
10 | const bannerText = 'Stream React Conf on May 15-16.';
11 | const bannerLink = 'https://conf.react.dev/';
12 | const bannerLinkText = 'Learn more.';
13 |
14 | export default function SocialBanner() {
15 | const ref = useRef(null);
16 | useEffect(() => {
17 | function patchedScrollTo(x: number, y: number) {
18 | if (y === 0) {
19 | // We're trying to reset scroll.
20 | // If we already scrolled past the banner, consider it as y = 0.
21 | const bannerHeight = ref.current?.offsetHeight ?? 0; // Could be zero (e.g. mobile)
22 | y = Math.min(window.scrollY, bannerHeight);
23 | }
24 | return realScrollTo(x, y);
25 | }
26 | const realScrollTo = window.scrollTo;
27 | (window as any).scrollTo = patchedScrollTo;
28 | return () => {
29 | (window as any).scrollTo = realScrollTo;
30 | };
31 | }, []);
32 | return (
33 |
38 | {bannerText}
39 |
42 | {bannerLinkText}
43 |
44 |
45 | );
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/MDX/Diagram.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import Image from 'next/image';
6 |
7 | interface DiagramProps {
8 | name: string;
9 | alt: string;
10 | height: number;
11 | width: number;
12 | children: string;
13 | captionPosition: 'top' | 'bottom' | null;
14 | }
15 |
16 | function Caption({text}: {text: string}) {
17 | return (
18 |
19 |
20 | {text}
21 |
22 |
23 | );
24 | }
25 |
26 | export function Diagram({
27 | name,
28 | alt,
29 | height,
30 | width,
31 | children,
32 | captionPosition,
33 | }: DiagramProps) {
34 | return (
35 |
36 | {captionPosition === 'top' && }
37 |
38 |
44 |
45 |
46 |
52 |
53 | {(!captionPosition || captionPosition === 'bottom') && (
54 |
55 | )}
56 |
57 | );
58 | }
59 |
60 | export default Diagram;
61 |
--------------------------------------------------------------------------------
/src/components/PageHeading.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import Breadcrumbs from 'components/Breadcrumbs';
6 | import Tag from 'components/Tag';
7 | import {H1} from './MDX/Heading';
8 | import type {RouteTag, RouteItem} from './Layout/getRouteMeta';
9 | import * as React from 'react';
10 | import {IconCanary} from './Icon/IconCanary';
11 |
12 | interface PageHeadingProps {
13 | title: string;
14 | canary?: boolean;
15 | status?: string;
16 | description?: string;
17 | tags?: RouteTag[];
18 | breadcrumbs: RouteItem[];
19 | }
20 |
21 | function PageHeading({
22 | title,
23 | status,
24 | canary,
25 | tags = [],
26 | breadcrumbs,
27 | }: PageHeadingProps) {
28 | return (
29 |
30 |
31 | {breadcrumbs ? : null}
32 |
33 | {title}
34 | {canary && (
35 |
39 | )}
40 | {status ? —{status} : ''}
41 |
42 | {tags?.length > 0 && (
43 |
44 | {tags.map((tag) => (
45 |
46 | ))}
47 |
48 | )}
49 |
50 |
51 | );
52 | }
53 |
54 | export default PageHeading;
55 |
--------------------------------------------------------------------------------
/src/content/reference/react/apis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 内置的 React API
3 | translators:
4 | - loveloki
5 | - Yucohny
6 | ---
7 |
8 |
9 |
10 | 除了 [Hooks](/reference/react) 和 [Components](/reference/react/components) 之外,`react` 包还导出了一些其他的 API,这些 API 对于创建组件非常有用。本页面将介绍这些剩余的 React API。
11 |
12 |
13 |
14 | ---
15 |
16 | * [`createContext`](/reference/react/createContext) API 可以创建一个 context,你可以将其提供给子组件,通常会与 [`useContext`](/reference/react/useContext) 一起配合使用。
17 | * [`forwardRef`](/reference/react/forwardRef) 允许组件将 DOM 节点作为 ref 暴露给父组件。
18 | * [`lazy`](/reference/react/lazy) 允许你延迟加载组件,直到该组件需要第一次被渲染。
19 | * [`memo`](/reference/react/memo) 允许你在 props 没有变化的情况下跳过组件的重渲染。通常 [`useMemo`](/reference/react/useMemo) 与 [`useCallback`](/reference/react/useCallback) 会一起配合使用。
20 | * [`startTransition`](/reference/react/startTransition) 允许你可以标记一个状态更新是不紧急的。类似于 [`useTransition`](/reference/react/useTransition)。
21 | * [`act`](/reference/react/act) 允许你在测试中包装渲染和交互,以确保在断言之前已完成更新。
22 |
23 | ---
24 |
25 | ## Resource APIs {/*resource-apis*/}
26 |
27 | *Resources* can be accessed by a component without having them as part of their state. For example, a component can read a message from a Promise or read styling information from a context.
28 |
29 | To read a value from a resource, use this API:
30 |
31 | * [`use`](/reference/react/use) lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context).
32 | ```js
33 | function MessageComponent({ messagePromise }) {
34 | const message = use(messagePromise);
35 | const theme = use(ThemeContext);
36 | // ...
37 | }
38 | ```
39 |
--------------------------------------------------------------------------------
/src/components/MDX/Link.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Facebook, Inc. and its affiliates.
3 | */
4 |
5 | import {Children, cloneElement} from 'react';
6 | import NextLink from 'next/link';
7 | import cn from 'classnames';
8 |
9 | import {ExternalLink} from 'components/ExternalLink';
10 |
11 | function Link({
12 | href,
13 | className,
14 | children,
15 | ...props
16 | }: React.AnchorHTMLAttributes) {
17 | const classes =
18 | 'inline text-link dark:text-link-dark border-b border-link border-opacity-0 hover:border-opacity-100 duration-100 ease-in transition leading-normal';
19 | const modifiedChildren = Children.toArray(children).map((child: any) => {
20 | if (child.type?.mdxName && child.type?.mdxName === 'inlineCode') {
21 | return cloneElement(child, {
22 | isLink: true,
23 | });
24 | }
25 | return child;
26 | });
27 |
28 | if (!href) {
29 | // eslint-disable-next-line jsx-a11y/anchor-has-content
30 | return ;
31 | }
32 | return (
33 | <>
34 | {href.startsWith('https://') ? (
35 |
36 | {modifiedChildren}
37 |
38 | ) : href.startsWith('#') ? (
39 | // eslint-disable-next-line jsx-a11y/anchor-has-content
40 |
41 | {modifiedChildren}
42 |
43 | ) : (
44 |
45 | {modifiedChildren}
46 |
47 | )}
48 | >
49 | );
50 | }
51 |
52 | export default Link;
53 |
--------------------------------------------------------------------------------
/src/content/reference/react-dom/components/progress.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "