Rename unitOfWork -> workInProgress
These values represent fibers that are incomplete. In the current model they're mutated in place. In a completely immutable model they would need to be cloned for every step they make progress. I.e. one where the child is still in this WIP state and one when it is complete. To clarify this I'll name them workInProgress while they're in that state, which is also what Jordan did in his prototype.
Sebastian Markbage committed
Jun 6, 2016 at 22:10 UTC
3a32d2642f435b68b939a528db09482c5a43b3fa
3 files changed
+73
-73
src/renderers/shared/fiber/ReactFiberBeginWork.js
+45
-45
@@ -27,114 +27,114 @@ var {
27
YieldComponent,
28
} = ReactTypesOfWork;
29
30
-function updateFunctionalComponent(unitOfWork) {
31
- var fn = unitOfWork.type;
32
- var props = unitOfWork.input;
30
+function updateFunctionalComponent(workInProgress) {
31
+ var fn = workInProgress.type;
32
+ var props = workInProgress.input;
33
console.log('update fn:', fn.name);
34
var nextChildren = fn(props);
35
36
- unitOfWork.child = ReactChildFiber.reconcileChildFibers(
37
- unitOfWork,
38
- unitOfWork.child,
36
+ workInProgress.child = ReactChildFiber.reconcileChildFibers(
37
+ workInProgress,
38
+ workInProgress.child,
39
nextChildren
40
);
41
}
42
43
-function updateHostComponent(unitOfWork) {
44
- console.log('host component', unitOfWork.type, typeof unitOfWork.input.children === 'string' ? unitOfWork.input.children : '');
43
+function updateHostComponent(workInProgress) {
44
+ console.log('host component', workInProgress.type, typeof workInProgress.input.children === 'string' ? workInProgress.input.children : '');
45
46
- var nextChildren = unitOfWork.input.children;
47
- unitOfWork.child = ReactChildFiber.reconcileChildFibers(
48
- unitOfWork,
49
- unitOfWork.child,
46
+ var nextChildren = workInProgress.input.children;
47
+ workInProgress.child = ReactChildFiber.reconcileChildFibers(
48
+ workInProgress,
49
+ workInProgress.child,
50
nextChildren
51
);
52
}
53
54
-function mountIndeterminateComponent(unitOfWork) {
55
- var fn = unitOfWork.type;
56
- var props = unitOfWork.input;
54
+function mountIndeterminateComponent(workInProgress) {
55
+ var fn = workInProgress.type;
56
+ var props = workInProgress.input;
57
var value = fn(props);
58
if (typeof value === 'object' && value && typeof value.render === 'function') {
59
console.log('performed work on class:', fn.name);
60
// Proceed under the assumption that this is a class instance
61
- unitOfWork.tag = ClassComponent;
61
+ workInProgress.tag = ClassComponent;
62
} else {
63
console.log('performed work on fn:', fn.name);
64
// Proceed under the assumption that this is a functional component
65
- unitOfWork.tag = FunctionalComponent;
65
+ workInProgress.tag = FunctionalComponent;
66
}
67
- unitOfWork.child = ReactChildFiber.reconcileChildFibers(
68
- unitOfWork,
69
- unitOfWork.child,
67
+ workInProgress.child = ReactChildFiber.reconcileChildFibers(
68
+ workInProgress,
69
+ workInProgress.child,
70
value
71
);
72
}
73
74
-function updateCoroutineComponent(unitOfWork) {
75
- var coroutine = (unitOfWork.input : ?ReactCoroutine);
74
+function updateCoroutineComponent(workInProgress) {
75
+ var coroutine = (workInProgress.input : ?ReactCoroutine);
76
if (!coroutine) {
77
throw new Error('Should be resolved by now');
78
}
79
- console.log('begin coroutine', unitOfWork.type.name);
80
- unitOfWork.child = ReactChildFiber.reconcileChildFibers(
81
- unitOfWork,
82
- unitOfWork.child,
79
+ console.log('begin coroutine', workInProgress.type.name);
80
+ workInProgress.child = ReactChildFiber.reconcileChildFibers(
81
+ workInProgress,
82
+ workInProgress.child,
83
coroutine.children
84
);
85
}
86
87
-function beginWork(unitOfWork : Fiber) : ?Fiber {
88
- const alt = unitOfWork.alternate;
89
- if (alt && unitOfWork.input === alt.memoizedInput) {
87
+function beginWork(workInProgress : Fiber) : ?Fiber {
88
+ const alt = workInProgress.alternate;
89
+ if (alt && workInProgress.input === alt.memoizedInput) {
90
// The most likely scenario is that the previous copy of the tree contains
91
// the same input as the new one. In that case, we can just copy the output
92
// and children from that node.
93
- unitOfWork.output = alt.output;
94
- unitOfWork.child = alt.child;
93
+ workInProgress.output = alt.output;
94
+ workInProgress.child = alt.child;
95
return null;
96
}
97
- if (unitOfWork.input === unitOfWork.memoizedInput) {
97
+ if (workInProgress.input === workInProgress.memoizedInput) {
98
// In a ping-pong scenario, this version could actually contain the
99
// old input. In that case, we can just bail out.
100
return null;
101
}
102
- switch (unitOfWork.tag) {
102
+ switch (workInProgress.tag) {
103
case IndeterminateComponent:
104
- mountIndeterminateComponent(unitOfWork);
104
+ mountIndeterminateComponent(workInProgress);
105
break;
106
case FunctionalComponent:
107
- updateFunctionalComponent(unitOfWork);
107
+ updateFunctionalComponent(workInProgress);
108
break;
109
case ClassComponent:
110
- console.log('class component', unitOfWork.input.type.name);
110
+ console.log('class component', workInProgress.input.type.name);
111
break;
112
case HostComponent:
113
- updateHostComponent(unitOfWork);
113
+ updateHostComponent(workInProgress);
114
break;
115
case CoroutineHandlerPhase:
116
// This is a restart. Reset the tag to the initial phase.
117
- unitOfWork.tag = CoroutineComponent;
117
+ workInProgress.tag = CoroutineComponent;
118
// Intentionally fall through since this is now the same.
119
case CoroutineComponent:
120
- updateCoroutineComponent(unitOfWork);
120
+ updateCoroutineComponent(workInProgress);
121
// This doesn't take arbitrary time so we could synchronously just begin
122
- // eagerly do the work of unitOfWork.child as an optimization.
123
- if (unitOfWork.child) {
124
- return beginWork(unitOfWork.child);
122
+ // eagerly do the work of workInProgress.child as an optimization.
123
+ if (workInProgress.child) {
124
+ return beginWork(workInProgress.child);
125
}
126
break;
127
case YieldComponent:
128
// A yield component is just a placeholder, we can just run through the
129
// next one immediately.
130
- if (unitOfWork.sibling) {
131
- return beginWork(unitOfWork.sibling);
130
+ if (workInProgress.sibling) {
131
+ return beginWork(workInProgress.sibling);
132
}
133
return null;
134
default:
135
throw new Error('Unknown unit of work tag');
136
}
137
- return unitOfWork.child;
137
+ return workInProgress.child;
138
}
139
140
exports.beginWork = beginWork;
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+19
-19
@@ -54,8 +54,8 @@ function recursivelyFillYields(yields, output : ?Fiber | ?ReifiedYield) {
54
}
55
}
56
57
-function moveCoroutineToHandlerPhase(unitOfWork : Fiber) {
58
- var coroutine = (unitOfWork.input : ?ReactCoroutine);
57
+function moveCoroutineToHandlerPhase(workInProgress : Fiber) {
58
+ var coroutine = (workInProgress.input : ?ReactCoroutine);
59
if (!coroutine) {
60
throw new Error('Should be resolved by now');
61
}
@@ -67,12 +67,12 @@ function moveCoroutineToHandlerPhase(unitOfWork : Fiber) {
67
// So this requires nested handlers.
68
// Note: This doesn't mutate the alternate node. I don't think it needs to
69
// since this stage is reset for every pass.
70
- unitOfWork.tag = CoroutineHandlerPhase;
70
+ workInProgress.tag = CoroutineHandlerPhase;
71
72
// Build up the yields.
73
// TODO: Compare this to a generator or opaque helpers like Children.
74
var yields : Array<ReifiedYield> = [];
75
- var child = unitOfWork.child;
75
+ var child = workInProgress.child;
76
while (child) {
77
recursivelyFillYields(yields, child.output);
78
child = child.sibling;
@@ -81,34 +81,34 @@ function moveCoroutineToHandlerPhase(unitOfWork : Fiber) {
81
var props = coroutine.props;
82
var nextChildren = fn(props, yields);
83
84
- unitOfWork.stateNode = ReactChildFiber.reconcileChildFibers(
85
- unitOfWork,
86
- unitOfWork.stateNode,
84
+ workInProgress.stateNode = ReactChildFiber.reconcileChildFibers(
85
+ workInProgress,
86
+ workInProgress.stateNode,
87
nextChildren
88
);
89
- return unitOfWork.stateNode;
89
+ return workInProgress.stateNode;
90
}
91
92
-exports.completeWork = function(unitOfWork : Fiber) : ?Fiber {
93
- switch (unitOfWork.tag) {
92
+exports.completeWork = function(workInProgress : Fiber) : ?Fiber {
93
+ switch (workInProgress.tag) {
94
case FunctionalComponent:
95
- console.log('/functional component', unitOfWork.type.name);
96
- transferOutput(unitOfWork.child, unitOfWork);
95
+ console.log('/functional component', workInProgress.type.name);
96
+ transferOutput(workInProgress.child, workInProgress);
97
break;
98
case ClassComponent:
99
- console.log('/class component', unitOfWork.type.name);
100
- transferOutput(unitOfWork.child, unitOfWork);
99
+ console.log('/class component', workInProgress.type.name);
100
+ transferOutput(workInProgress.child, workInProgress);
101
break;
102
case HostComponent:
103
- console.log('/host component', unitOfWork.type);
103
+ console.log('/host component', workInProgress.type);
104
break;
105
case CoroutineComponent:
106
- console.log('/coroutine component', unitOfWork.input.handler.name);
107
- return moveCoroutineToHandlerPhase(unitOfWork);
106
+ console.log('/coroutine component', workInProgress.input.handler.name);
107
+ return moveCoroutineToHandlerPhase(workInProgress);
108
case CoroutineHandlerPhase:
109
- transferOutput(unitOfWork.stateNode, unitOfWork);
109
+ transferOutput(workInProgress.stateNode, workInProgress);
110
// Reset the tag to now be a first phase coroutine.
111
- unitOfWork.tag = CoroutineComponent;
111
+ workInProgress.tag = CoroutineComponent;
112
break;
113
case YieldComponent:
114
// Does nothing.
src/renderers/shared/fiber/ReactFiberReconciler.js
+9
-9
@@ -49,23 +49,23 @@ module.exports = function<T, P, I>(config : HostConfig<T, P, I>) : Reconciler {
49
50
let nextUnitOfWork : ?Fiber = null;
51
52
- function completeUnitOfWork(unitOfWork : Fiber) : ?Fiber {
52
+ function completeUnitOfWork(workInProgress : Fiber) : ?Fiber {
53
while (true) {
54
- var next = completeWork(unitOfWork);
54
+ var next = completeWork(workInProgress);
55
if (next) {
56
// If completing this work spawned new work, do that next.
57
return next;
58
- } else if (unitOfWork.sibling) {
58
+ } else if (workInProgress.sibling) {
59
// If there is more work to do in this parent, do that next.
60
- return unitOfWork.sibling;
61
- } else if (unitOfWork.parent) {
60
+ return workInProgress.sibling;
61
+ } else if (workInProgress.parent) {
62
// If there's no more work in this parent. Complete the parent.
63
// TODO: Stop using the parent for this purpose. I think this will break
64
// down in edge cases because when nodes are reused during bailouts, we
65
// don't know which of two parents was used. Instead we should maintain
66
// a temporary manual stack.
67
// $FlowFixMe: This downcast is not safe. It is intentionally an error.
68
- unitOfWork = unitOfWork.parent;
68
+ workInProgress = workInProgress.parent;
69
} else {
70
// If we're at the root, there's no more work to do.
71
return null;
@@ -73,14 +73,14 @@ module.exports = function<T, P, I>(config : HostConfig<T, P, I>) : Reconciler {
73
}
74
}
75
76
- function performUnitOfWork(unitOfWork : Fiber) : ?Fiber {
77
- var next = beginWork(unitOfWork);
76
+ function performUnitOfWork(workInProgress : Fiber) : ?Fiber {
77
+ var next = beginWork(workInProgress);
78
if (next) {
79
// If this spawns new work, do that next.
80
return next;
81
} else {
82
// Otherwise, complete the current work.
83
- return completeUnitOfWork(unitOfWork);
83
+ return completeUnitOfWork(workInProgress);
84
}
85
}
86