`'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 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。
@@ -955,38 +959,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'
}];
```
@@ -1016,9 +1020,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)` 来读取它。
@@ -1094,38 +1098,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'
}];
```
@@ -1153,7 +1157,7 @@ li {
-Note how components in the middle don't need to pass `imageSize` anymore.
+请注意中间的组件是怎样实现不用传入 `imageSize` 参数的。