Schedule side-effects to parents before their children
This is only for host nodes so that the DOM tree is fully updated by the time we've flushed. Classes will schedule their life-cycles *after* their children's side-effects.
Sebastian Markbage committed
Jun 30, 2016 at 01:05 UTC
c6b5622bffa92e358f12ac21d485aac67bb4f8d9
1 file changed
+21
-13
src/renderers/shared/fiber/ReactFiberCompleteWork.js
+21
-13
@@ -17,8 +17,6 @@ import type { Fiber } from 'ReactFiber';
17
import type { HostConfig } from 'ReactFiberReconciler';
18
import type { ReifiedYield } from 'ReactReifiedYield';
19
20
-import type { TypeOfWork } from 'ReactTypeOfWork';
21
-
20
var ReactChildFiber = require('ReactChildFiber');
21
var ReactTypeOfWork = require('ReactTypeOfWork');
22
var {
@@ -37,8 +35,20 @@ module.exports = function<T, P, I, C>(config : HostConfig<T, P, I, C>) {
35
const createInstance = config.createInstance;
36
const prepareUpdate = config.prepareUpdate;
37
38
+ function markForPreEffect(workInProgress : Fiber) {
39
+ // Schedule a side-effect on this fiber, BEFORE the children's side-effects.
40
+ if (workInProgress.firstEffect) {
41
+ workInProgress.nextEffect = workInProgress.firstEffect;
42
+ workInProgress.firstEffect = workInProgress;
43
+ } else {
44
+ workInProgress.firstEffect = workInProgress;
45
+ workInProgress.lastEffect = workInProgress;
46
+ }
47
+ }
48
+
49
+ /*
50
function markForPostEffect(workInProgress : Fiber) {
41
- // Schedule a side-effect on this fiber, after the children's side-effects.
51
+ // Schedule a side-effect on this fiber, AFTER the children's side-effects.
52
if (workInProgress.lastEffect) {
53
workInProgress.lastEffect.nextEffect = workInProgress;
54
} else {
@@ -46,6 +56,7 @@ module.exports = function<T, P, I, C>(config : HostConfig<T, P, I, C>) {
56
}
57
workInProgress.lastEffect = workInProgress;
58
}
59
+ */
60
61
function transferOutput(child : ?Fiber, returnFiber : Fiber) {
62
// If we have a single result, we just pass that through as the output to
@@ -124,13 +135,11 @@ module.exports = function<T, P, I, C>(config : HostConfig<T, P, I, C>) {
135
case HostContainer:
136
transferOutput(workInProgress.child, workInProgress);
137
// We don't know if a container has updated any children so we always
127
- // need to update it right now. We schedule this side-effect after
128
- // all the other side-effects in the subtree.
129
- // TODO: I just realized that this means that nodes are not in the DOM
130
- // document when componentDidMount/Update fires. I'll need to change
131
- // the order for host component effects to happen *before* their
132
- // children I think.
133
- markForPostEffect(workInProgress);
138
+ // need to update it right now. We schedule this side-effect before
139
+ // all the other side-effects in the subtree. We need to schedule it
140
+ // before so that the entire tree is up-to-date before the life-cycles
141
+ // are invoked.
142
+ markForPreEffect(workInProgress);
143
return null;
144
case HostComponent:
145
console.log('/host component', workInProgress.type);
@@ -138,15 +147,14 @@ module.exports = function<T, P, I, C>(config : HostConfig<T, P, I, C>) {
147
const children = (child && !child.sibling) ? (child.output : ?Fiber | I) : child;
148
const newProps = workInProgress.pendingProps;
149
workInProgress.memoizedProps = newProps;
141
- if (workInProgress.alternate && workInProgress.stateNode != null) {
150
+ if (current && workInProgress.stateNode != null) {
151
// If we have an alternate, that means this is an update and we need to
152
// schedule a side-effect to do the updates.
144
- const current = workInProgress.alternate;
153
const oldProps = current.memoizedProps;
154
const instance : I = workInProgress.stateNode;
155
if (prepareUpdate(instance, oldProps, newProps, children)) {
156
// This returns true if there was something to update.
149
- markForPostEffect(workInProgress);
157
+ markForPreEffect(workInProgress);
158
}
159
workInProgress.output = instance;
160
} else {