1
1
# 第一部分
2
2
3
- 这是教程的第一部分。这是教程中最重要的部分, 你将在其中了解 Fiber 及其结构与字段的详细说明,为渲染器创建与宿主环境相关的配置并将渲染器注入开发者工具中 。
3
+ 这是教程的第一部分,也是教程最重要的部分, 你将在其中了解 Fiber 及其结构与属性的详细说明,为你的渲染器创建宿主环境配置并将渲染器注入开发工具中 。
4
4
5
- 在这个部分,我们将使用 [ ` react-reconciler ` ] ( https://github.com/facebook/react/tree/master/packages/react-reconciler ) 包创建一个 React 调度器。我们将使用 Fiber 实现渲染器。初期 ,React 使用 ** 栈渲染器** ,它是在传统的 JavaScript 栈上实现 。另一方面,Fiber 受代数效应和函数式思维的影响。它可以被认为是一个 JavaScript 对象,其中包含组件、输入和输出的信息 。
5
+ 在这个部分,我们将使用 [ ` react-reconciler ` ] ( https://github.com/facebook/react/tree/master/packages/react-reconciler ) 包创建一个 React 调度器。我们将使用 Fiber 实现渲染器。起初 ,React 使用 ** 栈渲染器** ,它是在 JavaScript 的调用栈上实现 。另一方面,Fiber 受代数效应和函数式编程思维的影响。它可以被认为是一个包含组件输入和输出的信息的 JavaScript 对象。
6
6
7
- 在我们继续之前,我建议你阅读 [ 这个 ] ( https://github .com/acdlite/react-fiber-architecture ) 文档 [ Andrew Clark ] (https://twitter .com/ acdlite?lang=en)。这会让你容易些 。
7
+ 在我们继续之前,我建议你阅读由 [ Andrew Clark ] ( https://twitter .com/acdlite?lang=en ) 写的 [ 这篇 ] ( https://github .com/acdlite/react-fiber-architecture ) 文章。这会让你更容易理解本教程 。
8
8
9
9
让我们开始!
10
10
11
- 我们将首先安装这些依赖 。
11
+ 我们首先安装这些依赖 。
12
12
13
13
``` bash
14
14
npm install react-reconciler fbjs
15
15
```
16
16
17
- 让我们从 ` react-reconciler ` 导入 ` Reconciler ` ,然后导入其它模块 。
17
+ 让我们从 ` react-reconciler ` 引入 ` Reconciler ` ,接着引入其它模块 。
18
18
19
19
``` js
20
20
import Reconciler from ' react-reconciler' ;
@@ -23,9 +23,9 @@ import emptyObject from 'fbjs/lib/emptyObject';
23
23
import { createElement } from ' ./utils/createElement' ;
24
24
```
25
25
26
- 注意我们还导入了 ` createElement ` 函数。别担心,我们稍后会实现它。
26
+ 注意我们还引入了 ` createElement ` 函数。别担心,我们稍后会实现它。
27
27
28
- 我们将传入 ** host config** 对象到 ` Reconciler ` 创建一个实例 。在这个对象中,我们将定义一些可以被认为是渲染器生命周期的方法 (更新、添加子组件、删除子组件、提交)。 React 将管理所有非宿主组件。
28
+ 我们传入 ** host config** 对象到 ` Reconciler ` 中来创建一个它的实例 。在这个对象中,我们将定义一些可以认为是渲染器生命周期的方法 (更新、添加子组件、删除子组件、提交)。 React 将管理所有非宿主组件。
29
29
30
30
``` js
31
31
const WordRenderer = Reconciler ({
@@ -70,7 +70,7 @@ const WordRenderer = Reconciler({
70
70
},
71
71
72
72
getRootHostContext (rootInstance ) {
73
- // 你可以使用此 'rootInstance' 从根传递数据 。
73
+ // 你可以使用此 'rootInstance' 从根节点传递数据 。
74
74
},
75
75
76
76
getChildHostContext () {
@@ -87,44 +87,43 @@ const WordRenderer = Reconciler({
87
87
});
88
88
```
89
89
90
- 让我们分析一下我们的 host config -
90
+ 让我们分析一下我们的宿主配置 -
91
91
92
92
** ` createInstance ` **
93
93
94
- 这个方法根据 ` type ` 、` props ` 和 ` internalInstanceHandle ` 创建一个组件实例 。
94
+ 这个方法根据 ` type ` 、` props ` 和 ` internalInstanceHandle ` 创建组件实例 。
95
95
96
96
例子 - 假设我们渲染如下内容,
97
97
98
98
``` js
99
99
< Text > Hello World< / Text >
100
100
```
101
101
102
- ` createInstance ` 将返回元素的 ` type ` (' TEXT ')、` props ` ( { children: 'Hello World' } )和根元素的实例(` WordDocument ` )信息。
102
+ ` createInstance ` 方法中将获得元素的 ` type ` (' TEXT ')、` props ` ( { children: 'Hello World' } )和根元素的实例(` WordDocument ` )信息。
103
103
104
104
** Fiber**
105
105
106
- Fiber 是组件需要完成或已经完成的工作 。最多,一个组件实例有两个 Fiber,已完成的 Fiber 和进行中的 Fiber。
106
+ Fiber 是组件需要或已经完成的工作 。最多,一个组件实例有两个 Fiber,已完成的 Fiber 和进行中的 Fiber。
107
107
108
- ` internalInstanceHandle ` 包含的信息有 ` tag ` 、` type ` 、` key ` 、` stateNode ` 和工作完成后退回的 Fiber。这个对象(Fiber)未来包含的信息有 -
108
+ ` internalInstanceHandle ` 包含的信息有 ` tag ` 、` type ` 、` key ` 、` stateNode ` 和工作完成后会退回去的 Fiber。这个对象(Fiber)包含的信息有 -
109
109
110
110
* ** ` tag ` ** - Fiber 的类型。
111
- * ** ` key ` ** - 子元素的唯一标识 。
112
- * ** ` type ` ** - 该 Fiber 关联的方法、类、模块 。
111
+ * ** ` key ` ** - 子节点的唯一标识 。
112
+ * ** ` type ` ** - 该 Fiber 关联的方法、类或模块 。
113
113
* ** ` stateNode ` ** - 该 Fiber 关联的本地状态。
114
114
115
- * ** ` return ` ** - 当前 Fiber 执行完毕后将要退回的 Fiber(父 Fiber)。
115
+ * ** ` return ` ** - 当前 Fiber 执行完毕后将要回退回去的 Fiber(父 Fiber)。
116
116
* ** ` child ` ** - ` child ` 、` sibling ` 和 ` index ` 表达 ** 单向列表数据结构** 。
117
117
* ** ` sibling ` **
118
118
* ** ` index ` **
119
119
* ** ` ref ` ** - ref 最终用于关联这个节点。
120
120
121
- * ** ` pendingProps ` ** - 该属性用于标签重载时 。
121
+ * ** ` pendingProps ` ** - 该属性用于标签发生重载时 。
122
122
* ** ` memoizedProps ` ** - 该属性用于创建输出。
123
- * ** ` updateQueue ` ** - 用于状态更新和回调的队列 。
123
+ * ** ` updateQueue ` ** - 状态更新和回调的队列 。
124
124
* ** ` memoizedState ` ** - 该状态用于创建输出。
125
125
126
- * ** ` internalContextTag ` ** - 位运算数据结构。Fiber 使用位运算数据结构来保存有关 Fiber 及其子树的信息序列,该子树存储在相邻的计算机内存位置。该属性中的位用于确定属性的状态。称为标志的位域集合表示操作的结果或某些中间状态。React Fiber 使用 AsyncUpdates 标志来指示子树是否是异步的。
127
- * ** ` effectTag ` ** - 副作用标记。
126
+ * ** ` subtreeFlags ` ** - 位标志。Fiber 使用位标志来保存有关 Fiber 及其子树的一些表示操作状态或某些中间状态。
128
127
* ** ` nextEffect ` ** - 在单向链表中快速到下一个具有副作用的 Fiber。
129
128
* ** ` firstEffect ` ** - 子树中有副作用的第一个(firstEffect)和最后一个(lastEffect)Fiber。重用此 Fiber 中已经完成的工作。
130
129
@@ -139,7 +138,7 @@ Fiber 是组件需要完成或已经完成的工作。最多,一个组件实
139
138
140
139
** ` appendInitialChild ` **
141
140
142
- 它用于添加子组件。如果子组件包含在父组件中 (例如:` Document ` ),那么我们将添加所有子组件到父组件中 ,否则我们将在父节点上创建一个名为 ` document ` 的属性并将所有子节点添加给它 。
141
+ 它用于添加子节点。如果子节点包含在父节点中 (例如:` Document ` ),那么我们将添加所有子节点到父节点中 ,否则我们将在父节点上创建一个名为 ` document ` 的属性后添加所有子节点 。
143
142
144
143
例子 -
145
144
@@ -149,15 +148,15 @@ const data = document.render(); // 返回输出
149
148
150
149
** ` prepareUpdate ` **
151
150
152
- 它计算实例的差异。即使 Fiber 暂停或中止对树的一部分渲染 ,也可以重用这项工作。
151
+ 它计算实例的差异。即使 Fiber 暂停或中止对树的部分渲染 ,也可以重用这项工作。
153
152
154
153
** ` commitUpdate ` **
155
154
156
155
提交更新或将计算的差异应用到宿主环境的节点 (WordDocument)。
157
156
158
157
** ` commitMount ` **
159
158
160
- 渲染器挂载宿主组件 ,但可能会在表单自动获得焦点之后进行一些工作。仅当没有当前或备用(alternate) Fiber 时才挂载宿主组件。
159
+ 渲染器挂载宿主节点 ,但可能会在表单自动获得焦点之后进行一些工作。仅当没有当前或备用(alternate) Fiber 时才挂载宿主组件。
161
160
162
161
** ` hostContext ` **
163
162
@@ -177,47 +176,47 @@ const data = document.render(); // 返回输出
177
176
178
177
** ` removeChild and removeChildFromContainer ` **
179
178
180
- 当我们在一个被移除的宿主组件中时,现在可以从树中移除节点 。如果返回的 Fiber 是容器,那么我们使用 ` removeChildFromContainer ` 从容器中删除节点,否则我们使用 ` removeChild ` 。
179
+ 从树中移除节点 。如果返回的 Fiber 是容器,那么我们使用 ` removeChildFromContainer ` 从容器中删除节点,否则我们使用 ` removeChild ` 。
181
180
182
181
** ` insertBefore ` **
183
182
184
- 它是一个 ` commitPlacement ` 钩子,在所有节点递归插入父节点时调用。这被抽象为 ` getHostSibling ` 的函数,该函数会持续搜索树,直到找到同级宿主节点(React 可能会在下一个版本中改变这种方法,因为它不是一种高效的方法,因为它会导致指数级的搜索复杂性) 。
183
+ 在目标节点之前插入一个子节点 。
185
184
186
185
** ` appendChildToContainer ` **
187
186
188
187
如果 Fiber 的类型是 ` HostRoot ` 或 ` HostPortal ` ,则将子节点添加到该容器中。
189
188
190
189
** ` appendChild ` **
191
190
192
- 添加子节点到父节点中 。
191
+ 向目标节点添加子节点 。
193
192
194
193
** ` shouldSetTextContent ` **
195
194
196
- 如果它返回 false,则重置文本内容 。
195
+ 如果它返回 false,重置文本内容 。
197
196
198
197
** ` getHostContext ` **
199
198
200
- 它用于标记当前的宿主上下文(根节点实例),用于发送更的内容,从而更新正在进行的 Fiber 队列(可能表示存在变化)。
199
+ 用于标记当前的宿主上下文(根元素实例),发送更新的内容,从而更新正在进行中的 Fiber 队列(可能表示存在变化)。
201
200
202
201
** ` createTextInstance ` **
203
202
204
203
创建文本节点的实例。
205
204
206
205
** ` supportsMutation ` **
207
206
208
- ` True ` 用于 ** 可变渲染器** ,其中宿主目标具有像 DOM 中的 ` appendChild ` 这样的可变 API。
207
+ ` true ` 为 ** 可变渲染器** 模式,其中宿主目标需要具有像 DOM 中的 ` appendChild ` 这样的可变 API。
209
208
210
- ### Note
209
+ ### 注意
211
210
212
- * 你 ** 不应该** 依赖 Fiber 的数据结构。将其字段视为私有 。
213
- * 将 'internalInstanceHandle' 对象视为一个黑盒 。
211
+ * 你 ** 不应该** 依赖 Fiber 的数据结构。将其属性视为私有 。
212
+ * 将 'internalInstanceHandle' 对象视为黑盒 。
214
213
* 使用宿主上下文方法从根节点获取数据。
215
214
216
215
> 在与 [ Dan Abramov] ( https://twitter.com/dan_abramov ) 讨论宿主配置方法和 Fiber 属性后,将上述要点添加到教程中。
217
216
218
217
## 将第三方渲染器注入开发工具中
219
218
220
- 你还可以将渲染器注入 react-devtools 以调试环境的宿主组件 。早期,注入第三方渲染器是不可能的,但现在使用返回的 ` reconciler ` 实例,可以将渲染器注入 react-devtools。
219
+ 你还可以将渲染器注入 react-devtools 以调试你环境中的宿主组件 。早期,是无法适配第三方渲染器的,但现在可以使用返回的 ` reconciler ` 实例,将渲染器注入到 react-devtools。
221
220
222
221
** 使用**
223
222
@@ -263,7 +262,7 @@ module.exports = CustomRenderer;
263
262
const CustomRenderer = require (' ./reconciler' )
264
263
265
264
function render (element , target , callback ) {
266
- ... // 在这里,使用 CustomRenderer.updateContainer() 进行顶层更新 ,有关更多详细信息,请参阅 Part-IV。
265
+ ... // 在这里,使用 CustomRenderer.updateContainer() 进行从最顶层开始的更新 ,有关更多详细信息,请参阅 Part-IV。
267
266
CustomRenderer .injectIntoDevTools ({
268
267
bundleType: 1 , // 0 for PROD, 1 for DEV
269
268
version: ' 0.1.0' , // version for your renderer
@@ -273,10 +272,10 @@ function render(element, target, callback) {
273
272
}
274
273
```
275
274
276
- 我们完成了教程的第一部分。我知道仅通过阅读代码很难理解其中的某些概念 。开始的时候感觉很混沌,但是继续尝试,最终它会变得清晰 。刚开始学习 Fiber 架构的时候,我什么都不懂。我感到极为沮丧,但我在上述代码的每一部分都使用了 ` console.log() ` 并试图理解它的实现 ,然后出现了“芜湖 芜湖 ”的时刻,它最终帮助我构建了 [ redocx] (https://github.com/nitin42/redocx)。它是有点难以理解,但你终将会明白 。
275
+ 我们完成了教程的第一部分。我知道其中的某些概念仅通过阅读代码是很难理解的 。开始的时候感觉很混沌,但请继续尝试,最终它会逐渐变得清晰 。刚开始学习 Fiber 架构的时候,我什么都不懂。我感到极为沮丧,但我在上述代码的每一部分都使用了 ` console.log() ` 并试图理解它们 ,然后出现了“芜湖起飞 ”的时刻,最终帮助我构建了 [ redocx] (https://github.com/nitin42/redocx)。它是有点难理解,但你终将会搞懂 。
277
276
278
- 如果你仍然有任何疑问,我在 Twitter 上的 [ @NTulswani ] ( https://twitter.com/NTulswani ) 。
277
+ 如果你仍然有任何疑问,我在 Twitter 上 [ @NTulswani ] ( https://twitter.com/NTulswani ) 。
279
278
280
279
[ 更多渲染器的实际示例] ( https://github.com/facebook/react/tree/master/packages/react-reconciler#practical-examples )
281
280
282
- [ 继续第二部分]] ( ./part-two.md )
281
+ [ 继续第二部分]] ( ./part-two-zh_CN .md )
0 commit comments