Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80522 views
1
/**
2
* Copyright 2014-2015, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule ReactChildReconciler
10
* @typechecks static-only
11
*/
12
13
'use strict';
14
15
var ReactReconciler = require("./ReactReconciler");
16
17
var flattenChildren = require("./flattenChildren");
18
var instantiateReactComponent = require("./instantiateReactComponent");
19
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
20
21
/**
22
* ReactChildReconciler provides helpers for initializing or updating a set of
23
* children. Its output is suitable for passing it onto ReactMultiChild which
24
* does diffed reordering and insertion.
25
*/
26
var ReactChildReconciler = {
27
28
/**
29
* Generates a "mount image" for each of the supplied children. In the case
30
* of `ReactDOMComponent`, a mount image is a string of markup.
31
*
32
* @param {?object} nestedChildNodes Nested child maps.
33
* @return {?object} A set of child instances.
34
* @internal
35
*/
36
instantiateChildren: function(nestedChildNodes, transaction, context) {
37
var children = flattenChildren(nestedChildNodes);
38
for (var name in children) {
39
if (children.hasOwnProperty(name)) {
40
var child = children[name];
41
// The rendered children must be turned into instances as they're
42
// mounted.
43
var childInstance = instantiateReactComponent(child, null);
44
children[name] = childInstance;
45
}
46
}
47
return children;
48
},
49
50
/**
51
* Updates the rendered children and returns a new set of children.
52
*
53
* @param {?object} prevChildren Previously initialized set of children.
54
* @param {?object} nextNestedChildNodes Nested child maps.
55
* @param {ReactReconcileTransaction} transaction
56
* @param {object} context
57
* @return {?object} A new set of child instances.
58
* @internal
59
*/
60
updateChildren: function(
61
prevChildren,
62
nextNestedChildNodes,
63
transaction,
64
context) {
65
// We currently don't have a way to track moves here but if we use iterators
66
// instead of for..in we can zip the iterators and check if an item has
67
// moved.
68
// TODO: If nothing has changed, return the prevChildren object so that we
69
// can quickly bailout if nothing has changed.
70
var nextChildren = flattenChildren(nextNestedChildNodes);
71
if (!nextChildren && !prevChildren) {
72
return null;
73
}
74
var name;
75
for (name in nextChildren) {
76
if (!nextChildren.hasOwnProperty(name)) {
77
continue;
78
}
79
var prevChild = prevChildren && prevChildren[name];
80
var prevElement = prevChild && prevChild._currentElement;
81
var nextElement = nextChildren[name];
82
if (shouldUpdateReactComponent(prevElement, nextElement)) {
83
ReactReconciler.receiveComponent(
84
prevChild, nextElement, transaction, context
85
);
86
nextChildren[name] = prevChild;
87
} else {
88
if (prevChild) {
89
ReactReconciler.unmountComponent(prevChild, name);
90
}
91
// The child must be instantiated before it's mounted.
92
var nextChildInstance = instantiateReactComponent(
93
nextElement,
94
null
95
);
96
nextChildren[name] = nextChildInstance;
97
}
98
}
99
// Unmount children that are no longer present.
100
for (name in prevChildren) {
101
if (prevChildren.hasOwnProperty(name) &&
102
!(nextChildren && nextChildren.hasOwnProperty(name))) {
103
ReactReconciler.unmountComponent(prevChildren[name]);
104
}
105
}
106
return nextChildren;
107
},
108
109
/**
110
* Unmounts all rendered children. This should be used to clean up children
111
* when this component is unmounted.
112
*
113
* @param {?object} renderedChildren Previously initialized set of children.
114
* @internal
115
*/
116
unmountChildren: function(renderedChildren) {
117
for (var name in renderedChildren) {
118
var renderedChild = renderedChildren[name];
119
ReactReconciler.unmountComponent(renderedChild);
120
}
121
}
122
123
};
124
125
module.exports = ReactChildReconciler;
126
127