You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Co-authored-by: KnowsCount <knowscount@gmail.com>
Co-authored-by: yang <yyyanghj@gmail.com>
Co-authored-by: Tina Pu <t2pu@uwaterloo.ca>
Co-authored-by: QiChang Li <github@liqichang.com>
Copy file name to clipboardExpand all lines: beta/src/pages/learn/scaling-up-with-reducer-and-context.md
+60-54Lines changed: 60 additions & 54 deletions
Original file line number
Diff line number
Diff line change
@@ -1,24 +1,29 @@
1
1
---
2
-
title: Scaling Up with Reducer and Context
2
+
title: 使用 Reducer 和 Context 来拓展你的应用
3
+
translators:
4
+
- Ikaite
5
+
- KnowsCount
6
+
- TinaaaaP
7
+
- yyyang1996
3
8
---
4
9
5
10
<Intro>
6
11
7
-
Reducers let you consolidate a component's state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen.
In this example from [the introduction to reducers](/learn/extracting-state-logic-into-a-reducer), the state is managed by a reducer. The reducer function contains all of the state update logic and is declared at the bottom of this file:
A reducer helps keep the event handlers short and concise. However, as your app grows, you might run into another difficulty. **Currently, the `tasks`state and the `dispatch`function are only available in the top-level `TaskApp`component.** To let other components read the list of tasks or change it, you have to explicitly [pass down](/learn/passing-props-to-a-component)the current state and the event handlers that change it as props.
For example, `TaskApp` passes a list of tasks and the event handlers to `TaskList`:
213
219
214
220
```js
@@ -219,7 +225,7 @@ For example, `TaskApp` passes a list of tasks and the event handlers to `TaskLis
219
225
/>
220
226
```
221
227
222
-
And `TaskList`passes the event handlers to `Task`:
228
+
`TaskList`将事件处理程序传递给 `Task`:
223
229
224
230
```js
225
231
<Task
@@ -229,34 +235,34 @@ And `TaskList` passes the event handlers to `Task`:
229
235
/>
230
236
```
231
237
232
-
In a small example like this, this works well, but if you have tens or hundreds of components in the middle, passing down all state and functions can be quite frustrating!
238
+
在像这样的小示例里这样做没什么问题,但是如果你有成千上百个组件,传递所有状态和函数可能会非常麻烦!
233
239
234
240
<!--(TODO: illustration of prop drilling)-->
235
241
236
-
This is why, as an alternative to passing them through props, you might want to put both the `tasks`state and the `dispatch`function [into context](/learn/passing-data-deeply-with-context). **This way, any component below `TaskApp`in the tree can read the tasks and dispatch actions without the repetitive "prop drilling".**
### Step 2: Put state and dispatch into context {/*step-2-put-state-and-dispatch-into-context*/}
463
+
### 第二步: 将 state 和 dispatch 函数 放入 context {/*step-2-put-state-and-dispatch-into-context*/}
458
464
459
-
Now you can import both contexts in your `TaskApp`component. Take the`tasks`and`dispatch`returned by `useReducer()` and [provide them](/learn/passing-data-deeply-with-context#step-3-provide-the-context)to the entire tree below:
**The `TaskApp`component does not pass any event handlers down, and the `TaskList`does not pass any event handlers to the `Task` component either.** Each component reads the context that it needs:
**The state still "lives" in the top-level `TaskApp` component, managed with `useReducer`.** But its`tasks`and`dispatch` are now available to every component below in the tree by importing and using these contexts.
You don't have to do this, but you could further declutter the components by moving both reducer and context into a single file. Currently, `TasksContext.js` contains only two context declarations:
This file is about to get crowded! You'll move the reducer into that same file. Then you'll declare a new `TasksProvider`component in the same file. This component will tie all the pieces together:
You can also export functions that _use_ the context from `TasksContext.js`:
1134
+
你也可以从 `TasksContext.js` 中导出使用 context 的函数:
1129
1135
1130
1136
```js
1131
1137
exportfunctionuseTasks() {
@@ -1137,14 +1143,14 @@ export function useTasksDispatch() {
1137
1143
}
1138
1144
```
1139
1145
1140
-
When a component needs to read context, it can do it through these functions:
1146
+
组件可以通过以下函数读取 context:
1141
1147
1142
1148
```js {5-7}
1143
1149
consttasks=useTasks();
1144
1150
constdispatch=useTasksDispatch();
1145
1151
```
1146
1152
1147
-
This doesn't change the behavior in any way, but it lets you later split these contexts further or add some logic to these functions. **Now all of the context and reducer wiring is in `TasksContext.js`. This keeps the components clean and uncluttered, focused on what they display rather than where they get the data:**
You can think of `TasksProvider`as a part of the screen that knows how to deal with tasks, `useTasks`as a way to read them, and `useTasksDispatch`as a way to update them from any component below in the tree.
> Functions like `useTasks`and`useTasksDispatch`are called **[Custom Hooks](/learn/reusing-logic-with-custom-hooks).** Your function is considered a custom Hook if its name starts with `use`. This lets you use other Hooks, like `useContext`, inside it.
As your app grows, you may have many context-reducer pairs like this. This is a powerful way to scale your app and [lift state up](/learn/sharing-state-between-components) without too much work whenever you want to access the data deep in the tree.
0 commit comments