From 39cdd2c785cf5a745daf8128aded1563167341aa Mon Sep 17 00:00:00 2001 From: KeanuoLeung Date: Sat, 27 Nov 2021 16:28:10 +0800 Subject: [PATCH 1/4] [Beta]: docs(cn): passing-data-deep-with-context into Chinese --- .../learn/passing-data-deeply-with-context.md | 399 +++++++++--------- 1 file changed, 201 insertions(+), 198 deletions(-) diff --git a/beta/src/pages/learn/passing-data-deeply-with-context.md b/beta/src/pages/learn/passing-data-deeply-with-context.md index a5ef5ca297..8aa04cffd8 100644 --- a/beta/src/pages/learn/passing-data-deeply-with-context.md +++ b/beta/src/pages/learn/passing-data-deeply-with-context.md @@ -1,33 +1,35 @@ --- -title: Passing Data Deeply with Context +title: 使用 Context 深层传递参数 +translators: + - KeanuoLeung --- -Usually, you will pass information from a parent component to a child component via props. But passing props can become verbose and inconvenient if you have to pass them through many components in the middle, or if many components in your app need the same information. Context lets the parent component make some information available to any component in the tree below it—no matter how deep—without passing it explicitly through props. +通常来说,你会通过 props 将信息从父组件传递到子组件。但是,如果你必须通过许多中间组件向下传递 props,或是在你应用中的许多组件需要相同的信息,传递 props 会变的十分冗长和不便。Context 允许父组件向其下层无论多深的任何组件提供信息,而无需通过 props 显式传递。 -- What "prop drilling" is -- How to replace repetitive prop passing with context -- What the common use cases are for context -- What the common alternatives are to context +- 什么是“逐层 props” +- 如何使用 context 代替重复的参数传递 +- context 的常见用法 +- context 的常见替代方案 -## The problem with passing props {/*the-problem-with-passing-props*/} +## 传递 props 带来的问题 {/*the-problem-with-passing-props*/} -[Passing props](/learn/passing-props-to-a-component) is a great way to explicitly pipe data through your UI tree to the components that use it. But it can become verbose and inconvenient when you need to pass some prop deeply through the tree, or if many components need the same prop. The nearest common ancestor could be far removed from the components that need data, and [lifting state up](/learn/sharing-state-between-components) that high can lead to a situation sometimes called "prop drilling." +[传递 props](/learn/passing-props-to-a-component) 是将数据通过 UI 树显式传递到使用它的组件的好方法。但是当你需要在组件树中深层传递参数以及需要在组件间复用相同的参数时,传递 props 就会变得很麻烦。最近的根节点父组件可能离需要数据的组件很远,[状态提升](/learn/sharing-state-between-components)到太高的层级会导致“逐层 props”的情况。 -Lifting state up vs prop drilling +状态提升 vs 逐层 props -Wouldn't it be great if there were a way to "teleport" data to the components in the tree that need it without passing props? With React's context feature, there is! +要是有一种方法可以在不传递 props 的情况下将数据“传送”到组件树中需要它的组件,那可就太好了。React 的 context 功能可以满足我们的这个心愿。 -## Context: an alternative to passing props {/*context-an-alternative-to-passing-props*/} +## Context:传递 props 的另一种方法 {/*context-an-alternative-to-passing-props*/} -Context lets a parent component provide data to the entire tree below it. There are many uses for context. Here is one example. Consider this `Heading` component that accepts a `level` for its size: +Context 可以让父组件向它下面的整个组件树提供数据。Context 有很多种用途。这里就有一个示例。考虑一下这个 `Heading` 组件,它接受一个 `level` 参数来决定它标题的尺寸: @@ -38,12 +40,12 @@ import Section from './Section.js'; export default function Page() { return (
- Title - Heading - Sub-heading - Sub-sub-heading - Sub-sub-sub-heading - Sub-sub-sub-sub-heading + 大标题 + 标题 + 小标题 + 小小标题 + 小小小标题 + 小小小小标题
); } @@ -75,7 +77,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -91,7 +93,7 @@ export default function Heading({ level, children }) {
-Let's say you want multiple headers within the same `Section` to always have the same size: +假设你想让同一个 `Section` 中的的多个标题都有相同的尺寸: @@ -102,19 +104,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + 大标题
- Heading - Heading - Heading + 标题 + 标题 + 标题
- Sub-heading - Sub-heading - Sub-heading + 小标题 + 小标题 + 小标题
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
@@ -149,7 +151,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -165,41 +167,41 @@ export default function Heading({ level, children }) { -Currently, you pass the `level` prop to each `` separately: +目前,你将 `level` 参数分别传递给每个 ``: ```js
- About - Photos - Videos + 关于 + 照片 + 视频
``` -It would be nice if you could pass the `level` prop to the `
` component instead and remove it from the ``. This way you could enforce that all headings in the same section have the same size: +将 `level` 参数传递给 `
` 组件而不是传给 `` 组件看起来更好一些。这样的话你可以强制使同一个 section 中的所有标题都有相同的尺寸: ```js
- About - Photos - Videos + 关于 + 照片 + 视频
``` -But how can the `` component know the level of its closest `
`? **That would require some way for a child to "ask" for data from somewhere above in the tree.** +但是 `` 组件是如何知道离它最近的 `
` 的 level 的呢?**这需要子组件可以通过某种方式“询问”到组件树中某处在其上层的数据。** -You can't do it with props alone. This is where context comes into play. You will do it in three steps: +你不能只通过 props 来实现它。这就是 context 大显身手的地方。你可以通过以下三个步骤来实现它: -1. **Create** a context. (You can call it `LevelContext`, since it's for the heading level.) -2. **Use** that context from the component that needs the data. (`Header` will use `LevelContext`.) -3. **Provide** that context from the component that specifies the data. (`Section` will provide `LevelContext`.) +1. **创建** 一个 context。(你可以将其命名为 `LevelContext`, 因为它表示的是标题级别。) +2. 在需要数据的组件内 **使用** 刚刚创建的 context。(`Header` 将会使用 `LevelContext`。) +3. 在指定数据的组件中 **提供** 这个 context。 (`Section` 将会提供 `LevelContext`。) -Context lets a parent--even a distant one!--provide some data to the entire tree inside of it. +Context 可以让父节点,甚至是很远的父节点都可以为其内部的整个组件树提供数据。 -Context provides data to the entire tree +Context 向整个组件树提供数据 -### Step 1: Create the context {/*step-1-create-the-context*/} +### Step 1:创建 context {/*step-1-create-the-context*/} -First, you need to create the context. You'll need to **export it from a file** so that your components can use it: +首先,你需要创建这个 context。你需要先 **将其从一个文件中导出**,这样你的组件才可以使用它: @@ -210,19 +212,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + 大标题
- Heading - Heading - Heading + 标题 + 标题 + 标题
- Sub-heading - Sub-heading - Sub-heading + 小标题 + 小标题 + 小标题
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
@@ -257,7 +259,7 @@ export default function Heading({ level, children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -279,18 +281,18 @@ export const LevelContext = createContext(1); -The only argument to `createContext` is the _default_ value. Here, `1` refers to the biggest heading level, but you could pass any kind of value (even an object). You will see the significance of the default value in the next step. +`createContext` 只需要 _default_(默认值)这么一个参数。在这里, `1` 表示最大的标题级别,但是你可以传递任何类型的值(甚至可以传入一个对象)。你将在下一个步骤中见识到默认值的意义。 -### Step 2: Use the context {/*step-2-use-the-context*/} +### Step 2:使用 Context {/*step-2-use-the-context*/} -Import the `useContext` Hook from React and your context: +从 React 中引入 `useContext` Hook 以及你刚刚创建的 context: ```js import { useContext } from 'react'; import { LevelContext } from './LevelContext.js'; ``` -Currently, the `Heading` component reads `level` from props: +目前,`Heading` 组件从 props 中读取 `level`: ```js export default function Heading({ level, children }) { @@ -298,7 +300,7 @@ export default function Heading({ level, children }) { } ``` -Instead, remove the `level` prop and read the value from the context you just imported, `LevelContext`: +删掉 `level` 参数并从你刚刚引入的 `LevelContext` 中读取值: ```js {2} export default function Heading({ children }) { @@ -307,29 +309,29 @@ export default function Heading({ children }) { } ``` -`useContext` is a Hook. Just like `useState` and `useReducer`, you can only call a Hook at the top level of a React component. **`useContext` tells React that the `Heading` component wants to read the `LevelContext`.** +`useContext` 是一个 Hook。和 `useState` 以及 `useReducer`一样,你只能在 React 组件的顶层调用 Hook。**`useContext` 告诉 React `Heading` 组件想要读取 `LevelContext`。** -Now that the `Heading` component doesn't have a `level` prop, you don't need to pass the level prop to `Heading` in your JSX like this anymore: +现在 `Heading` 组件没有 `level` 参数,你不需要再像这样在你的 JSX 中将 level 参数传递给 `Heading`: ```js
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
``` -Update the JSX so that it's the `Section` that receives it instead: +修改一下 JSX,让 `Section` 组件代替 `Heading` 组件接收 level 参数: ```jsx
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
``` -As a reminder, this is the markup that you were trying to get working: +你将修改下边的代码直到它正常运行: @@ -340,19 +342,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + 大标题
- Heading - Heading - Heading + 标题 + 标题 + 标题
- Sub-heading - Sub-heading - Sub-heading + 小标题 + 小标题 + 小标题
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
@@ -391,7 +393,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -413,13 +415,13 @@ export const LevelContext = createContext(1); -Notice this example doesn't quite work, yet! All the headers have the same size because **even though you're *using* the context, you have not *provided* it yet.** React doesn't know where to get it! +注意!这个例子还不能运行。所有标题的尺寸都一样,因为**即使你正在*使用* context,但是你还没有*提供*它。** React 不知道从哪里获取这个 context! -If you don't provide the context, React will use the default value you've specified in the previous step. In this example, you specified `1` as the argument to `createContext`, so `useContext(LevelContext)` returns `1`, setting all those headings to `

`. Let's fix this problem by having each `Section` provide its own context. +如果你不提供 context,React 会使用你在上一步指定的默认值。在这个例子中,你为 `createContext` 传入了 `1` 这个参数,所以 `useContext(LevelContext)` 会返回 `1`,把所有的标题。我们通过让每个 `Section` 提供它自己的 context 来修复这个问题。 -### Step 3: Provide the context {/*step-3-provide-the-context*/} +### Step 3:提供 context {/*step-3-provide-the-context*/} -The `Section` component currently renders its children: +`Section` 组件目前渲染传入它的子组件: ```js export default function Section({ children }) { @@ -431,7 +433,7 @@ export default function Section({ children }) { } ``` -**Wrap them with a context provider** to provide the `LevelContext` to them: +**把它们用 context provider 包裹起来** 以提供 `LevelContext` 给它们: ```js {1,6,8} import { LevelContext } from './LevelContext.js'; @@ -447,7 +449,7 @@ export default function Section({ level, children }) { } ``` -This tells React: "if any component inside this `
` asks for `LevelContext`, give them this `level`." The component will use the value of the nearest `` in the UI tree above it. +这告诉 React:“如果在 `
` 组件中的任何子组件请求 `LevelContext`,给他们这个 `level`。”组件会使用 UI 树中在它上层最近的那个 `` 传递过来的值。 @@ -458,19 +460,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + 大标题
- Heading - Heading - Heading + 标题 + 标题 + 标题
- Sub-heading - Sub-heading - Sub-heading + 小标题 + 小标题 + 小标题
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
@@ -513,7 +515,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -535,15 +537,15 @@ export const LevelContext = createContext(1); -It's the same result as the original code, but you did not need to pass the `level` prop to each `Heading` component! Instead, it "figures out" its heading level by asking the closest `Section` above: +这与原始代码的运行结果相同,但是你不需要向每个 `Heading` 组件传递 `level` 参数了!相反,它通过询问上层最近的 `Section` 来“断定”它的标题级别: -1. You pass a `level` prop to the `
`. -2. `Section` wraps its children into ``. -3. `Header` asks the closest value of `LevelContext` above with `useContext(LevelContext)`. +1. 你将一个 `level` 参数传递给 `
`。 +2. `Section` 把它的子元素包在 `` 里面。 +3. `Header` 使用 `useContext(LevelContext)` 询问上层最近的 `LevelContext` 提供的值。 -## Using and providing context from the same component {/*using-and-providing-context-from-the-same-component*/} +## 在相同的组件中使用并提供 context {/*using-and-providing-context-from-the-same-component*/} -Currently, you still have to specify each section's `level` manually: +目前,你仍需要手动指定每个 section 的 `level`: ```js export default function Page() { @@ -556,7 +558,8 @@ export default function Page() { ... ``` -Since context lets you read information from a component above, each `Section` could read the `level` from the `Section` above, and pass `level + 1` down automatically. Here is how you could do it: +由于 context 让你可以从上层的组件读取信息,每个 `Section` 都会从上层的 `Section` 读取 `level`,并自动向下层传递 `level + 1`。 +你可以像下面这样做: ```js Section.js {5,8} import { useContext } from 'react'; @@ -574,7 +577,7 @@ export default function Section({ children }) { } ``` -With this change, you don't need to pass the `level` prop *either* to the `
` or to the ``: +这样修改之后,你不用将 `level` 参数传给 `
` *或者是* ``: @@ -585,19 +588,19 @@ import Section from './Section.js'; export default function Page() { return (
- Title + 大标题
- Heading - Heading - Heading + 标题 + 标题 + 标题
- Sub-heading - Sub-heading - Sub-heading + 小标题 + 小标题 + 小标题
- Sub-sub-heading - Sub-sub-heading - Sub-sub-heading + 小小标题 + 小小标题 + 小小标题
@@ -630,7 +633,7 @@ export default function Heading({ children }) { const level = useContext(LevelContext); switch (level) { case 0: - throw Error('Heading must be inside a Section!'); + throw Error('Heading 必须在 Section 内部!'); case 1: return

{children}

; case 2: @@ -644,7 +647,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -666,15 +669,15 @@ export const LevelContext = createContext(0); -Now both `Heading` and `Section` read the `LevelContext` to figure out how "deep" they are. And the `Section` wraps its children into the `LevelContext` to specify that anything inside of it is at a "deeper" level. + 现在,`Heading` 和 `Section` 都通过读取 `LevelContext` 来判断它们的深度。而且 `Section` 把它的子组件都包在 `LevelContext` 中来指定其中的任何内容都处于一个“更深”的级别。 ->This example uses heading levels because they show visually how nested components can override context. But context is useful for many other use cases too. You can use it to pass down any information needed by the entire subtree: the current color theme, the currently logged in user, and so on. +>本示例使用标题级别来展示,因为它们直观地显示了嵌套组件如何覆盖 context。但是 context 对于许多其他的场景也很有用。你可以用它来传递整个子树需要的任何信息:当前的颜色主题、当前登录的用户等。 -## Context passes through intermediate components {/*context-passes-through-intermediate-components*/} +## Context 会穿过中间层级的组件 {/*context-passes-through-intermediate-components*/} -You can insert as many components as you like between the component that provides context and the one that uses it. This includes both built-in components like `
` and components you might build yourself. +你可以在提供 context 的组件和使用它的组件之间的层级插入任意数量的组件。这包括像 `
` 这样的内置组件和你自己创建的组件。 -In this example, the same `Post` component (with a dashed border) is rendered at two different nesting levels. Notice that the `` inside of it gets its level automatically from the closest `
`: +在这个示例中,相同的 `Post` 组件(带有虚线边框)在两个不同的嵌套层级上渲染。注意,它内部的 `` 会自动从最近的 `
` 获取它的级别: @@ -687,8 +690,8 @@ export default function ProfilePage() {
My Profile
@@ -698,7 +701,7 @@ export default function ProfilePage() { function AllPosts() { return (
- Posts + 帖子
); @@ -707,14 +710,14 @@ function AllPosts() { function RecentPosts() { return (
- Recent Posts + 最近的帖子
); @@ -759,7 +762,7 @@ export default function Heading({ children }) { const level = useContext(LevelContext); switch (level) { case 0: - throw Error('Heading must be inside a Section!'); + throw Error('Heading 必须在 Section 内部!'); case 1: return

{children}

; case 2: @@ -773,7 +776,7 @@ export default function Heading({ children }) { case 6: return
{children}
; default: - throw Error('Unknown level: ' + level); + throw Error('未知的 level:' + level); } } ``` @@ -799,60 +802,60 @@ export const LevelContext = createContext(0);
-You didn't do anything special for this to work. A `Section` specifies the context for the tree inside it, so you can insert a `` anywhere, and it will have the correct size. Try it in the sandbox above! +你没有做任何特别的事情来让它运行。`Section` 为它内部的树指定一个 context,所以你可以在任何地方插入一个 ``,而且它会有正确的尺寸。在上边的沙箱中尝试一下! -**Context lets you write components that "adapt to their surroundings" and display themselves differently depending on _where_ (or, in other words, _in which context_) they are being rendered.** +**Context 让你可以编写“适应周围环境”的组件,并且根据 _在哪_ (或者说 _在哪个 context 中_)来渲染它们不同的样子。** -How context works might remind you of [CSS property inheritance](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance). In CSS, you can specify `color: blue` for a `
`, and any DOM node inside of it, no matter how deep, will inherit that color unless some other DOM node in the middle overrides it with `color: green`. Similarly, in React, the only way to override some context coming from above is to wrap children into a context provider with a different value. +Context 的工作方式可能会让你想起 [CSS 属性继承](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance)。在 CSS 中,你可以为一个 `
` 手动指定 `color: blue`,并且其中的任何 DOM 节点,无论多深,都会继承那个颜色,除非中间的其他 DOM 节点用 `color: green` 来覆盖它。类似地,在 React 中,覆盖来自上层的某些 context 的唯一方法是将子组件包裹到一个提供不同值的 context provider 中。 -In CSS, different properties like `color` and `background-color` don't override each other. You can set all `
`'s `color` to red without impacting `background-color`. Similarly, **different React contexts don't override each other**. Each context that you make with `createContext()` is completely separate from other ones, and ties together components using and providing *that particular* context. One component may use or provide many different contexts without a problem. +在 CSS 中,诸如 `color` 和 `background-color` 之类的不同属性不会覆盖彼此。你可以设置所有 `
` 的 `color` 为红色,而不会影像 `background-color`。类似地,**不同的 React context 不会覆盖彼此**。你通过 `createContext()` 创建的每个 context 都和其他 context 完全分离,只有使用和提供 *那个特定的* context 的组件才会联系在一起。一个组件可以轻松地使用或者提供许多不同的 context。 -## Before you use context {/*before-you-use-context*/} +## 写在你使用 context 之前 {/*before-you-use-context*/} -Context is very tempting to use! However, this also means it's too easy to overuse it. **Just because you need to pass some props several levels deep doesn't mean you should put that information into context.** +使用 Context 看起来非常诱人!然而,这也意味着它也太容易被过度使用了。**如果你只想把一些 props 传递到多个层级中,这并不意味着你需要把这些信息放到 context 里。** -Here's a few alternatives you should consider before using context: +在使用 context 之前,你可以考虑以下几种替代方案: -1. **Start by [passing props](/learn/passing-props-to-a-component).** If your components are not trivial, it's not unusual to pass a dozen props down through a dozen components. It may feel like a slog, but it makes it very clear which components use which data! The person maintaining your code will be glad you've made the data flow explicit with props. -2. **Extract components and [pass JSX as `children`](/learn/passing-props-to-a-component#passing-jsx-as-children) to them.** If you pass some data through many layers of intermediate components that don't use that data (and only pass it further down), this often means that you forgot to extract some components along the way. For example, maybe you pass data props like `posts` to visual components that don't use them directly, like ``. Instead, make `Layout` take `children` as a prop, and render ``. This reduces the number of layers between the component specifying the data and the one that needs it. +1. **从 [传递 props](/learn/passing-props-to-a-component) 开始。** 如果你的组件看起来不起眼,那么通过十几个组件向下传递一堆 props 并不罕见。这有点像是在埋头苦干,但是这样做可以让哪些组件用了哪些数据变得十分清晰!维护你代码的人会很高兴你用 props 让数据流变得更加清晰。 +2. **抽象组件并 [将 JSX 作为 `children` 传递](/learn/passing-props-to-a-component#passing-jsx-as-children) 给它们。** 如果你通过很多层不使用该数据的中间组件(并且只会向下传递)来传递数据,这通常意味着你在此过程中忘记了抽象组件。举个例子,你可能想传递一些像 `posts` 的数据 props 到不会直接使用这个参数的组件,类似 ``。相反,让 `Layout` 把 `children` 当做一个参数,然后渲染 ``。这样就减少了定义数据的组件和使用数据的组件之间的层级。 -If neither of these approaches works well for you, consider context. +如果这两种方法都不适合你,再考虑使用 context。 -## Use cases for context {/*use-cases-for-context*/} +## Context 的使用场景 {/*use-cases-for-context*/} -* **Theming:** If your app lets the user change its appearance (e.g. dark mode), you can put a context provider at the top of your app, and use that context in components that need to adjust their visual look. -* **Current account:** Many components might need to know the currently logged in user. Putting it in context makes it convenient to read it anywhere in the tree. Some apps also let you operate multiple accounts at the same time (e.g. to leave a comment as a different user). In those cases, it can be convenient to wrap a part of the UI into a nested provider with a different current account value. -* **Routing:** Most routing solutions use context internally to hold the current route. This is how every link "knows" whether it's active or not. If you build your own router, you might want to do it too. -* **Managing state:** As your app grows, you might end up with a lot of state closer to the top of your app. Many distant components below may want to change it. It is common to [use a reducer together with context](/learn/scaling-up-with-reducer-and-context) to manage complex state and pass it down to distant components without too much hassle. +* **主题:** 如果你的应用允许用户更改其外观(例如暗夜模式),你可以在应用顶层放一个 context provider,并在需要调整其外观的组件中使用该 context。 +* **当前账户:** 许多组件可能需要知道当前登录的用户信息。将它放到 context 中可以方便地在书中的任何位置读取它。某些应用还允许你同事操作多个账户(例如,以不同用户的身份发表评论)。在这些情况下,将 UI 的一部分包裹到具有不同账户数据的 provider 中会很方便。 +* **路由:** 大多数路由解决方案在其内部使用 context 来保存当前路由。这就是每个链接“知道”它是否处于活动状态的方式。如果你创建自己的路由库,你可能也会这么做。 +* **状态管理:** 随着你的应用的增长,你最终可能在靠近应用顶部的位置有很多 state。下层的许多遥远的组件可能想要修改他们。通常 [将 reducer 与 context 搭配使用](/learn/scaling-up-with-reducer-and-context)来管理复杂的状态并将其传递给深层的组件而不会有太多麻烦。 -Context is not limited to static values. If you pass a different value on the next render, React will update all the components reading it below! This is why context is often used in combination with state. +Context 不局限于静态值。如果你在下一次渲染时传递不同的值,React 将会更新下层读取它的所有组件!这就是 context 经常和 state 结合使用的原因。 -In general, if some information is needed by distant components in different parts of the tree, it's a good indication that context will help you. +一般而言,如果树中不同部分的远距离组件需要某些信息,context 将会对你大有帮助。 -Context provides data to the entire tree +Context 向整棵树提供数据 -* Context lets a component provide some information to the entire tree below it. -* To pass context: - 1. Create and export it with `export const MyContext = createContext(defaultValue)`. - 2. Pass it to the `useContext(MyContext)` Hook to read it in any child component, no matter how deep. - 3. Wrap children into `` to provide it from a parent. -* Context passes through any components in the middle. -* Context lets you write components that "adapt to their surroundings." -* Before you use context, try passing props or passing JSX as `children`. +* Context 使组件向其下方的整个树提供信息。 +* 传递 Context 的方法: + 1. 通过 `export const MyContext = createContext(defaultValue)` 创建并导出 context。 + 2. 在无论层级多深的任何子组件中,把 context 传递给 `useContext(MyContext)` Hook 来读取它。 + 3. 在父组件中把 children 包在 `` 中来提供 context。 +* Context 会穿过中间的任何组件。 +* Context 让你写出“适应周围环境”的组件。 +* 在使用 context 之前,先试试传递 props 或者将 JSX 作为 `children` 传递。 -### Replace prop drilling with context {/*replace-prop-drilling-with-context*/} +### 用 context 替代逐层 props {/*replace-prop-drilling-with-context*/} -In this example, toggling the checkbox changes the `imageSize` prop passed to each ``. The checkbox state is held in the top-level `App` component, but each `` needs to be aware of it. +在这个示例中,切换复选框状态会修改传入每个 `` 的 `imageSize` 参数。复选框的 state 保存在顶层的 `App` 组件中,但是每个 `` 都需要注意它。 -Currently, `App` passes `imageSize` to `List`, which passes it to each `Place`, which passes it to the `PlaceImage`. Remove the `imageSize` prop, and instead pass it from the `App` component directly to `PlaceImage`. +目前,`App` 将 `imageSize` 传递给 `List`,`List` 再将其传递给每个 `Place`,`Place` 又将其传递给 `PlaceImage`。移除 `imageSize` 参数,并在 `App` 组件中直接将其传递给 `PlaceImage`。 -You can declare context in `Context.js`. +你可以在 `Context.js` 中声明 context。 @@ -928,38 +931,38 @@ function PlaceImage({ place, imageSize }) { ```js data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: '南非开普敦的海角上方', + description: '为房屋选择亮色的传统始于 20 世纪后期。', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: '中国台湾省台中市彩虹村', + description: '1924 年,当地居民黄永福为了避免拆迁,将 1200 间房屋全部粉刷。', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: '墨西哥的帕丘卡宏观壁画', + description: '世界上最大的壁画之一,覆盖了山坡上的房屋。', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people."', + name: '巴西里约热内卢的塞拉龙楼梯', + description: '这个地标由智利出生的艺术家 Jorge Selarón 创作,以“向巴西人民致敬”。', imageId: 'aeO3rpI' }, { id: 4, - name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + name: '意大利布拉诺', + description: '这些房屋按照一个可追溯到 16 世纪的特定颜色系统进行粉刷。', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.', + name: '摩洛哥舍夫沙万', + description: '关于为什么房屋被涂成蓝色,有几种理论,包括这几种颜色可以驱蚊或者它象征着天空和天堂。', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: '韩国釜山甘川文化村', + description: '2009 年,该村通过粉刷房屋并举办展览和艺术装置而转变为文化中心。', imageId: 'ZfQOOzf' }]; ``` @@ -989,9 +992,9 @@ li { -Remove `imageSize` prop from all the components. +移除掉所有组件中的 `imageSize` 参数。 -Create and export `ImageSizeContext` from `Context.js`. Then wrap the List into `` to pass the value down, and `useContext(ImageSizeContext)` to read it in the `PlaceImage`: +在 `Context.js` 中创建并导出 `ImageSizeContext`。然后用 `` 包裹住整个列表来向下传递值,最后在 `PlaceImage` 中使用 `useContext(ImageSizeContext)` 来读取它。 @@ -1067,38 +1070,38 @@ export const ImageSizeContext = createContext(500); ```js data.js export const places = [{ id: 0, - name: 'Bo-Kaap in Cape Town, South Africa', - description: 'The tradition of choosing bright colors for houses began in the late 20th century.', + name: '南非开普敦的海角上方', + description: '为房屋选择亮色的传统始于 20 世纪后期。', imageId: 'K9HVAGH' }, { id: 1, - name: 'Rainbow Village in Taichung, Taiwan', - description: 'To save the houses from demolition, Huang Yung-Fu, a local resident, painted all 1,200 of them in 1924.', + name: '中国台湾省台中市彩虹村', + description: '1924 年,当地居民黄永福为了避免拆迁,将 1200 间房屋全部粉刷。', imageId: '9EAYZrt' }, { id: 2, - name: 'Macromural de Pachuca, Mexico', - description: 'One of the largest murals in the world covering homes in a hillside neighborhood.', + name: '墨西哥的帕丘卡宏观壁画', + description: '世界上最大的壁画之一,覆盖了山坡上的房屋。', imageId: 'DgXHVwu' }, { id: 3, - name: 'Selarón Staircase in Rio de Janeiro, Brazil', - description: 'This landmark was created by Jorge Selarón, a Chilean-born artist, as a "tribute to the Brazilian people."', + name: '巴西里约热内卢的塞拉龙楼梯', + description: '这个地标由智利出生的艺术家 Jorge Selarón 创作,以“向巴西人民致敬”。', imageId: 'aeO3rpI' }, { id: 4, - name: 'Burano, Italy', - description: 'The houses are painted following a specific color system dating back to 16th century.', + name: '意大利布拉诺', + description: '这些房屋按照一个可追溯到 16 世纪的特定颜色系统进行粉刷。', imageId: 'kxsph5C' }, { id: 5, - name: 'Chefchaouen, Marocco', - description: 'There are a few theories on why the houses are painted blue, including that the color repells mosquitos or that it symbolizes sky and heaven.', + name: '摩洛哥舍夫沙万', + description: '关于为什么房屋被涂成蓝色,有几种理论,包括这几种颜色可以驱蚊或者它象征着天空和天堂。', imageId: 'rTqKo46' }, { id: 6, - name: 'Gamcheon Culture Village in Busan, South Korea', - description: 'In 2009, the village was converted into a cultural hub by painting the houses and featuring exhibitions and art installations.', + name: '韩国釜山甘川文化村', + description: '2009 年,该村通过粉刷房屋并举办展览和艺术装置而转变为文化中心。', imageId: 'ZfQOOzf' }]; ``` @@ -1126,7 +1129,7 @@ li { -Note how components in the middle don't need to pass `imageSize` anymore. +请注意中间的组件是怎样不再需要传递 `imageSize` 的。 From c602d0b057d066e4deb1340a61f55749af8c2708 Mon Sep 17 00:00:00 2001 From: JuvenileKeanuo Date: Tue, 30 Nov 2021 00:41:15 +0800 Subject: [PATCH 2/4] re-translate a sentence --- beta/src/pages/learn/passing-data-deeply-with-context.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beta/src/pages/learn/passing-data-deeply-with-context.md b/beta/src/pages/learn/passing-data-deeply-with-context.md index 8aa04cffd8..9638f13797 100644 --- a/beta/src/pages/learn/passing-data-deeply-with-context.md +++ b/beta/src/pages/learn/passing-data-deeply-with-context.md @@ -29,7 +29,7 @@ translators: ## Context:传递 props 的另一种方法 {/*context-an-alternative-to-passing-props*/} -Context 可以让父组件向它下面的整个组件树提供数据。Context 有很多种用途。这里就有一个示例。考虑一下这个 `Heading` 组件,它接受一个 `level` 参数来决定它标题的尺寸: +Context 可以让父组件向它下面的整个组件树提供数据。Context 有很多种用途。这里就有一个示例。考虑一下 `Heading` 组件接受一个 `level` 参数来决定它标题尺寸的情况: @@ -1133,4 +1133,4 @@ li { - \ No newline at end of file + From 4380d4f42ac34cc320d52222e62c1cdf878392da Mon Sep 17 00:00:00 2001 From: Keanuo Date: Thu, 9 Dec 2021 22:11:11 +0800 Subject: [PATCH 3/4] Update beta/src/pages/learn/passing-data-deeply-with-context.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 滑威 --- beta/src/pages/learn/passing-data-deeply-with-context.md | 1 + 1 file changed, 1 insertion(+) diff --git a/beta/src/pages/learn/passing-data-deeply-with-context.md b/beta/src/pages/learn/passing-data-deeply-with-context.md index 9638f13797..c679145a46 100644 --- a/beta/src/pages/learn/passing-data-deeply-with-context.md +++ b/beta/src/pages/learn/passing-data-deeply-with-context.md @@ -2,6 +2,7 @@ title: 使用 Context 深层传递参数 translators: - KeanuoLeung + - rottenpen --- From 7abacb1fe76ac73d020380fffcb71d036eb69088 Mon Sep 17 00:00:00 2001 From: JuvenileKeanuo Date: Thu, 9 Dec 2021 22:24:50 +0800 Subject: [PATCH 4/4] suggestions by @rottenpen --- .../learn/passing-data-deeply-with-context.md | 162 +++++++++--------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/beta/src/pages/learn/passing-data-deeply-with-context.md b/beta/src/pages/learn/passing-data-deeply-with-context.md index c679145a46..eca888218d 100644 --- a/beta/src/pages/learn/passing-data-deeply-with-context.md +++ b/beta/src/pages/learn/passing-data-deeply-with-context.md @@ -13,7 +13,7 @@ translators: -- 什么是“逐层 props” +- 什么是“prop 逐级透传” - 如何使用 context 代替重复的参数传递 - context 的常见用法 - context 的常见替代方案 @@ -26,11 +26,11 @@ translators: 状态提升 vs 逐层 props -要是有一种方法可以在不传递 props 的情况下将数据“传送”到组件树中需要它的组件,那可就太好了。React 的 context 功能可以满足我们的这个心愿。 +要是有一种方法可以在组件树中不需要 props 将数据“直达”到所需的组件中,那可就太好了。React 的 context 功能可以满足我们的这个心愿。 ## Context:传递 props 的另一种方法 {/*context-an-alternative-to-passing-props*/} -Context 可以让父组件向它下面的整个组件树提供数据。Context 有很多种用途。这里就有一个示例。考虑一下 `Heading` 组件接受一个 `level` 参数来决定它标题尺寸的情况: +Context 让父组件可以为它下面的整个组件树提供数据。Context 有很多种用途。这里就有一个示例。思考一下这个 `Heading` 组件接收一个 `level` 参数来决定它标题尺寸的场景: @@ -41,12 +41,12 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 - 标题 - 小标题 - 小小标题 - 小小小标题 - 小小小小标题 + 主标题 + 副标题 + 子标题 + 子子标题 + 子子子标题 + 子子子子标题
); } @@ -105,19 +105,19 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 + 主标题
- 标题 - 标题 - 标题 + 副标题 + 副标题 + 副标题
- 小标题 - 小标题 - 小标题 + 子标题 + 子标题 + 子标题
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
@@ -188,7 +188,7 @@ export default function Heading({ level, children }) {
``` -但是 `` 组件是如何知道离它最近的 `
` 的 level 的呢?**这需要子组件可以通过某种方式“询问”到组件树中某处在其上层的数据。** +但是 `` 组件是如何知道离它最近的 `
` 的 level 的呢?**这需要子组件可以通过某种方式“访问”到组件树中某处在其上层的数据。** 你不能只通过 props 来实现它。这就是 context 大显身手的地方。你可以通过以下三个步骤来实现它: @@ -202,7 +202,7 @@ Context 可以让父节点,甚至是很远的父节点都可以为其内部的 ### Step 1:创建 context {/*step-1-create-the-context*/} -首先,你需要创建这个 context。你需要先 **将其从一个文件中导出**,这样你的组件才可以使用它: +首先,你需要创建这个 context,并 **将其从一个文件中导出**,这样你的组件才可以使用它: @@ -213,19 +213,19 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 + 主标题
- 标题 - 标题 - 标题 + 副标题 + 副标题 + 副标题
- 小标题 - 小标题 - 小标题 + 子标题 + 子标题 + 子标题
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
@@ -282,7 +282,7 @@ export const LevelContext = createContext(1); -`createContext` 只需要 _default_(默认值)这么一个参数。在这里, `1` 表示最大的标题级别,但是你可以传递任何类型的值(甚至可以传入一个对象)。你将在下一个步骤中见识到默认值的意义。 +`createContext` 只需_默认值_这么一个参数。在这里, `1` 表示最大的标题级别,但是你可以传递任何类型的值(甚至可以传入一个对象)。你将在下一个步骤中见识到默认值的意义。 ### Step 2:使用 Context {/*step-2-use-the-context*/} @@ -316,9 +316,9 @@ export default function Heading({ children }) { ```js
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
``` @@ -326,9 +326,9 @@ export default function Heading({ children }) { ```jsx
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
``` @@ -343,19 +343,19 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 + 主标题
- 标题 - 标题 - 标题 + 副标题 + 副标题 + 副标题
- 小标题 - 小标题 - 小标题 + 子标题 + 子标题 + 子标题
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
@@ -461,19 +461,19 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 + 主标题
- 标题 - 标题 - 标题 + 副标题 + 副标题 + 副标题
- 小标题 - 小标题 - 小标题 + 子标题 + 子标题 + 子标题
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
@@ -538,11 +538,11 @@ export const LevelContext = createContext(1); -这与原始代码的运行结果相同,但是你不需要向每个 `Heading` 组件传递 `level` 参数了!相反,它通过询问上层最近的 `Section` 来“断定”它的标题级别: +这与原始代码的运行结果相同,但是你不需要向每个 `Heading` 组件传递 `level` 参数了!取而代之的是,它通过访问上层最近的 `Section` 来“断定”它的标题级别: 1. 你将一个 `level` 参数传递给 `
`。 2. `Section` 把它的子元素包在 `` 里面。 -3. `Header` 使用 `useContext(LevelContext)` 询问上层最近的 `LevelContext` 提供的值。 +3. `Header` 使用 `useContext(LevelContext)` 访问上层最近的 `LevelContext` 提供的值。 ## 在相同的组件中使用并提供 context {/*using-and-providing-context-from-the-same-component*/} @@ -578,7 +578,7 @@ export default function Section({ children }) { } ``` -这样修改之后,你不用将 `level` 参数传给 `
` *或者是* ``: +这样修改之后,你不用将 `level` 参数传给 `
` *或者是* `` 了: @@ -589,19 +589,19 @@ import Section from './Section.js'; export default function Page() { return (
- 大标题 + 主标题
- 标题 - 标题 - 标题 + 副标题 + 副标题 + 副标题
- 小标题 - 小标题 - 小标题 + 子标题 + 子标题 + 子标题
- 小小标题 - 小小标题 - 小小标题 + 子子标题 + 子子标题 + 子子标题
@@ -670,7 +670,7 @@ export const LevelContext = createContext(0); - 现在,`Heading` 和 `Section` 都通过读取 `LevelContext` 来判断它们的深度。而且 `Section` 把它的子组件都包在 `LevelContext` 中来指定其中的任何内容都处于一个“更深”的级别。 +现在,`Heading` 和 `Section` 都通过读取 `LevelContext` 来判断它们的深度。而且 `Section` 把它的子组件都包在 `LevelContext` 中来指定其中的任何内容都处于一个“更深”的级别。 >本示例使用标题级别来展示,因为它们直观地显示了嵌套组件如何覆盖 context。但是 context 对于许多其他的场景也很有用。你可以用它来传递整个子树需要的任何信息:当前的颜色主题、当前登录的用户等。 @@ -803,13 +803,13 @@ export const LevelContext = createContext(0); -你没有做任何特别的事情来让它运行。`Section` 为它内部的树指定一个 context,所以你可以在任何地方插入一个 ``,而且它会有正确的尺寸。在上边的沙箱中尝试一下! +你不需要做任何特殊的操作。`Section` 为它内部的树指定一个 context,所以你可以在任何地方插入一个 ``,而且它会有正确的尺寸。在上边的沙箱中尝试一下! **Context 让你可以编写“适应周围环境”的组件,并且根据 _在哪_ (或者说 _在哪个 context 中_)来渲染它们不同的样子。** Context 的工作方式可能会让你想起 [CSS 属性继承](https://developer.mozilla.org/en-US/docs/Web/CSS/inheritance)。在 CSS 中,你可以为一个 `
` 手动指定 `color: blue`,并且其中的任何 DOM 节点,无论多深,都会继承那个颜色,除非中间的其他 DOM 节点用 `color: green` 来覆盖它。类似地,在 React 中,覆盖来自上层的某些 context 的唯一方法是将子组件包裹到一个提供不同值的 context provider 中。 -在 CSS 中,诸如 `color` 和 `background-color` 之类的不同属性不会覆盖彼此。你可以设置所有 `
` 的 `color` 为红色,而不会影像 `background-color`。类似地,**不同的 React context 不会覆盖彼此**。你通过 `createContext()` 创建的每个 context 都和其他 context 完全分离,只有使用和提供 *那个特定的* context 的组件才会联系在一起。一个组件可以轻松地使用或者提供许多不同的 context。 +在 CSS 中,诸如 `color` 和 `background-color` 之类的不同属性不会覆盖彼此。你可以设置所有 `
` 的 `color` 为红色,而不会影响 `background-color`。类似地,**不同的 React context 不会覆盖彼此**。你通过 `createContext()` 创建的每个 context 都和其他 context 完全分离,只有使用和提供 *那个特定的* context 的组件才会联系在一起。一个组件可以轻松地使用或者提供许多不同的 context。 ## 写在你使用 context 之前 {/*before-you-use-context*/} @@ -818,18 +818,18 @@ Context 的工作方式可能会让你想起 [CSS 属性继承](https://develope 在使用 context 之前,你可以考虑以下几种替代方案: 1. **从 [传递 props](/learn/passing-props-to-a-component) 开始。** 如果你的组件看起来不起眼,那么通过十几个组件向下传递一堆 props 并不罕见。这有点像是在埋头苦干,但是这样做可以让哪些组件用了哪些数据变得十分清晰!维护你代码的人会很高兴你用 props 让数据流变得更加清晰。 -2. **抽象组件并 [将 JSX 作为 `children` 传递](/learn/passing-props-to-a-component#passing-jsx-as-children) 给它们。** 如果你通过很多层不使用该数据的中间组件(并且只会向下传递)来传递数据,这通常意味着你在此过程中忘记了抽象组件。举个例子,你可能想传递一些像 `posts` 的数据 props 到不会直接使用这个参数的组件,类似 ``。相反,让 `Layout` 把 `children` 当做一个参数,然后渲染 ``。这样就减少了定义数据的组件和使用数据的组件之间的层级。 +2. **抽象组件并 [将 JSX 作为 `children` 传递](/learn/passing-props-to-a-component#passing-jsx-as-children) 给它们。** 如果你通过很多层不使用该数据的中间组件(并且只会向下传递)来传递数据,这通常意味着你在此过程中忘记了抽象组件。举个例子,你可能想传递一些像 `posts` 的数据 props 到不会直接使用这个参数的组件,类似 ``。取而代之的是,让 `Layout` 把 `children` 当做一个参数,然后渲染 ``。这样就减少了定义数据的组件和使用数据的组件之间的层级。 如果这两种方法都不适合你,再考虑使用 context。 ## Context 的使用场景 {/*use-cases-for-context*/} * **主题:** 如果你的应用允许用户更改其外观(例如暗夜模式),你可以在应用顶层放一个 context provider,并在需要调整其外观的组件中使用该 context。 -* **当前账户:** 许多组件可能需要知道当前登录的用户信息。将它放到 context 中可以方便地在书中的任何位置读取它。某些应用还允许你同事操作多个账户(例如,以不同用户的身份发表评论)。在这些情况下,将 UI 的一部分包裹到具有不同账户数据的 provider 中会很方便。 +* **当前账户:** 许多组件可能需要知道当前登录的用户信息。将它放到 context 中可以方便地在书中的任何位置读取它。某些应用还允许你同时操作多个账户(例如,以不同用户的身份发表评论)。在这些情况下,将 UI 的一部分包裹到具有不同账户数据的 provider 中会很方便。 * **路由:** 大多数路由解决方案在其内部使用 context 来保存当前路由。这就是每个链接“知道”它是否处于活动状态的方式。如果你创建自己的路由库,你可能也会这么做。 -* **状态管理:** 随着你的应用的增长,你最终可能在靠近应用顶部的位置有很多 state。下层的许多遥远的组件可能想要修改他们。通常 [将 reducer 与 context 搭配使用](/learn/scaling-up-with-reducer-and-context)来管理复杂的状态并将其传递给深层的组件而不会有太多麻烦。 +* **状态管理:** 随着你的应用的增长,最终在靠近应用顶部的位置可能会有很多 state。许多遥远的下层组件可能想要修改它们。通常 [将 reducer 与 context 搭配使用](/learn/scaling-up-with-reducer-and-context)来管理复杂的状态并将其传递给深层的组件来避免过多的麻烦。 -Context 不局限于静态值。如果你在下一次渲染时传递不同的值,React 将会更新下层读取它的所有组件!这就是 context 经常和 state 结合使用的原因。 +Context 不局限于静态值。如果你在下一次渲染时传递不同的值,React 将会更新读取它的所有下层组件!这就是 context 经常和 state 结合使用的原因。 一般而言,如果树中不同部分的远距离组件需要某些信息,context 将会对你大有帮助。 @@ -932,7 +932,7 @@ function PlaceImage({ place, imageSize }) { ```js data.js export const places = [{ id: 0, - name: '南非开普敦的海角上方', + name: '南非开普敦的波卡普区', description: '为房屋选择亮色的传统始于 20 世纪后期。', imageId: 'K9HVAGH' }, { @@ -1071,7 +1071,7 @@ export const ImageSizeContext = createContext(500); ```js data.js export const places = [{ id: 0, - name: '南非开普敦的海角上方', + name: '南非开普敦的波卡普区', description: '为房屋选择亮色的传统始于 20 世纪后期。', imageId: 'K9HVAGH' }, { @@ -1130,7 +1130,7 @@ li { -请注意中间的组件是怎样不再需要传递 `imageSize` 的。 +请注意中间的组件是怎样实现不用传入 `imageSize` 参数的。