react 0.13.0-alpha.2 → 0.13.0-rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/JSXTransformer.js +1798 -1194
- package/dist/react-with-addons.js +2640 -2046
- package/dist/react-with-addons.min.js +7 -6
- package/dist/react.js +2459 -1930
- package/dist/react.min.js +6 -6
- package/lib/AutoFocusMixin.js +1 -1
- package/lib/BeforeInputEventPlugin.js +1 -5
- package/lib/CSSCore.js +1 -1
- package/lib/CSSProperty.js +3 -1
- package/lib/CSSPropertyOperations.js +43 -16
- package/lib/CallbackQueue.js +1 -1
- package/lib/ChangeEventPlugin.js +1 -1
- package/lib/ClientReactRootIndex.js +1 -1
- package/lib/DOMChildrenOperations.js +4 -43
- package/lib/DOMProperty.js +1 -1
- package/lib/DOMPropertyOperations.js +10 -15
- package/lib/Danger.js +1 -1
- package/lib/DefaultEventPluginOrder.js +2 -2
- package/lib/EnterLeaveEventPlugin.js +1 -1
- package/lib/EventConstants.js +1 -1
- package/lib/EventListener.js +1 -1
- package/lib/EventPluginHub.js +1 -1
- package/lib/EventPluginRegistry.js +1 -1
- package/lib/EventPluginUtils.js +3 -3
- package/lib/EventPropagators.js +1 -1
- package/lib/ExecutionEnvironment.js +1 -1
- package/lib/FallbackCompositionState.js +1 -1
- package/lib/HTMLDOMPropertyConfig.js +12 -5
- package/lib/LinkedStateMixin.js +1 -1
- package/lib/LinkedValueUtils.js +1 -1
- package/lib/LocalEventTrapMixin.js +9 -2
- package/lib/MobileSafariClickEventPlugin.js +1 -1
- package/lib/Object.assign.js +1 -1
- package/lib/PooledClass.js +1 -1
- package/lib/React.js +11 -14
- package/lib/ReactBrowserComponentMixin.js +1 -1
- package/lib/ReactBrowserEventEmitter.js +2 -2
- package/lib/ReactCSSTransitionGroup.js +1 -1
- package/lib/ReactCSSTransitionGroupChild.js +8 -5
- package/lib/ReactChildReconciler.js +9 -5
- package/lib/ReactChildren.js +3 -2
- package/lib/ReactClass.js +144 -76
- package/lib/ReactComponent.js +99 -166
- package/lib/ReactComponentBrowserEnvironment.js +1 -1
- package/lib/ReactComponentEnvironment.js +1 -1
- package/lib/ReactComponentWithPureRenderMixin.js +1 -1
- package/lib/ReactCompositeComponent.js +261 -480
- package/lib/ReactContext.js +13 -3
- package/lib/ReactCurrentOwner.js +1 -1
- package/lib/ReactDOM.js +1 -1
- package/lib/ReactDOMButton.js +1 -1
- package/lib/ReactDOMComponent.js +23 -48
- package/lib/ReactDOMForm.js +1 -1
- package/lib/ReactDOMIDOperations.js +3 -3
- package/lib/ReactDOMIframe.js +43 -0
- package/lib/ReactDOMImg.js +1 -1
- package/lib/ReactDOMInput.js +1 -1
- package/lib/ReactDOMOption.js +1 -1
- package/lib/ReactDOMSelect.js +1 -1
- package/lib/ReactDOMSelection.js +1 -1
- package/lib/ReactDOMTextComponent.js +3 -12
- package/lib/ReactDOMTextarea.js +1 -1
- package/lib/ReactDefaultBatchingStrategy.js +4 -4
- package/lib/ReactDefaultInjection.js +25 -1
- package/lib/ReactDefaultPerf.js +11 -3
- package/lib/ReactDefaultPerfAnalysis.js +1 -1
- package/lib/ReactElement.js +59 -4
- package/lib/ReactElementValidator.js +141 -85
- package/lib/ReactEmptyComponent.js +5 -5
- package/lib/ReactErrorUtils.js +1 -1
- package/lib/ReactEventEmitterMixin.js +1 -1
- package/lib/ReactEventListener.js +1 -2
- package/lib/ReactFragment.js +181 -0
- package/lib/ReactInjection.js +1 -1
- package/lib/ReactInputSelection.js +1 -1
- package/lib/ReactInstanceHandles.js +1 -1
- package/lib/ReactInstanceMap.js +1 -1
- package/lib/ReactLifeCycle.js +35 -0
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMarkupChecksum.js +1 -1
- package/lib/ReactMount.js +77 -20
- package/lib/ReactMultiChild.js +7 -4
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +33 -36
- package/lib/ReactOwner.js +1 -1
- package/lib/ReactPerf.js +1 -1
- package/lib/ReactPropTransferer.js +1 -1
- package/lib/ReactPropTypeLocationNames.js +1 -1
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +5 -3
- package/lib/ReactPutListenerQueue.js +1 -1
- package/lib/ReactReconcileTransaction.js +1 -1
- package/lib/ReactReconciler.js +120 -0
- package/lib/ReactRef.js +40 -67
- package/lib/ReactRootIndex.js +1 -1
- package/lib/ReactServerRendering.js +1 -1
- package/lib/ReactServerRenderingTransaction.js +1 -1
- package/lib/ReactStateSetters.js +1 -1
- package/lib/ReactTestUtils.js +48 -7
- package/lib/ReactTransitionChildMapping.js +7 -3
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +5 -5
- package/lib/ReactUpdateQueue.js +295 -0
- package/lib/ReactUpdates.js +11 -20
- package/lib/ReactWithAddons.js +3 -1
- package/lib/SVGDOMPropertyConfig.js +1 -1
- package/lib/SelectEventPlugin.js +1 -1
- package/lib/ServerReactRootIndex.js +1 -1
- package/lib/SimpleEventPlugin.js +3 -3
- package/lib/SyntheticClipboardEvent.js +1 -1
- package/lib/SyntheticCompositionEvent.js +1 -1
- package/lib/SyntheticDragEvent.js +1 -1
- package/lib/SyntheticEvent.js +1 -1
- package/lib/SyntheticFocusEvent.js +1 -1
- package/lib/SyntheticInputEvent.js +1 -1
- package/lib/SyntheticKeyboardEvent.js +1 -1
- package/lib/SyntheticMouseEvent.js +1 -1
- package/lib/SyntheticTouchEvent.js +1 -1
- package/lib/SyntheticUIEvent.js +1 -1
- package/lib/SyntheticWheelEvent.js +1 -1
- package/lib/Transaction.js +2 -2
- package/lib/ViewportMetrics.js +1 -1
- package/lib/accumulateInto.js +1 -1
- package/lib/adler32.js +1 -1
- package/lib/camelize.js +1 -1
- package/lib/camelizeStyleName.js +1 -1
- package/lib/cloneWithProps.js +4 -4
- package/lib/containsNode.js +1 -1
- package/lib/{createArrayFrom.js → createArrayFromMixed.js} +6 -6
- package/lib/createFullPageComponent.js +1 -1
- package/lib/createNodesFromMarkup.js +4 -4
- package/lib/cx.js +16 -1
- package/lib/dangerousStyleValue.js +1 -1
- package/lib/emptyFunction.js +1 -1
- package/lib/emptyObject.js +1 -1
- package/lib/{escapeTextForBrowser.js → escapeTextContentForBrowser.js} +4 -5
- package/lib/findDOMNode.js +19 -1
- package/lib/flattenChildren.js +1 -1
- package/lib/focusNode.js +1 -1
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getActiveElement.js +1 -1
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -1
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +1 -1
- package/lib/getMarkupWrap.js +1 -1
- package/lib/getNodeForCharacterOffset.js +1 -1
- package/lib/getReactRootElementInContainer.js +1 -1
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/getUnboundedScrollPosition.js +1 -1
- package/lib/hyphenate.js +1 -1
- package/lib/hyphenateStyleName.js +1 -1
- package/lib/instantiateReactComponent.js +20 -20
- package/lib/invariant.js +1 -1
- package/lib/isEventSupported.js +1 -1
- package/lib/isNode.js +1 -1
- package/lib/isTextInputElement.js +1 -1
- package/lib/isTextNode.js +1 -1
- package/lib/joinClasses.js +1 -1
- package/lib/keyMirror.js +1 -1
- package/lib/keyOf.js +1 -1
- package/lib/mapObject.js +1 -1
- package/lib/memoizeStringOnly.js +1 -1
- package/lib/onlyChild.js +1 -1
- package/lib/performance.js +1 -1
- package/lib/performanceNow.js +1 -1
- package/lib/quoteAttributeValueForBrowser.js +26 -0
- package/lib/setInnerHTML.js +1 -1
- package/lib/setTextContent.js +40 -0
- package/lib/shallowEqual.js +1 -1
- package/lib/shouldUpdateReactComponent.js +32 -10
- package/lib/toArray.js +2 -2
- package/lib/traverseAllChildren.js +18 -4
- package/lib/update.js +1 -1
- package/lib/warning.js +12 -1
- package/package.json +1 -1
- package/lib/ReactComponentBase.js +0 -126
- package/lib/accumulate.js +0 -47
- package/lib/copyProperties.js +0 -56
- package/lib/merge.js +0 -34
- package/lib/mergeInto.js +0 -24
- package/lib/monitorCodeUse.js +0 -30
package/lib/ReactComponent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2013-
|
|
2
|
+
* Copyright 2013-2015, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under the BSD-style license found in the
|
|
@@ -11,188 +11,121 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
var ReactOwner = require("./ReactOwner");
|
|
16
|
-
var ReactRef = require("./ReactRef");
|
|
14
|
+
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
17
15
|
|
|
18
16
|
var invariant = require("./invariant");
|
|
17
|
+
var warning = require("./warning");
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function detachRef(ref, component, owner) {
|
|
29
|
-
if (ref instanceof ReactRef) {
|
|
30
|
-
ReactRef.detachRef(ref, component);
|
|
31
|
-
} else {
|
|
32
|
-
ReactOwner.removeComponentAsRefFrom(component, ref, owner);
|
|
33
|
-
}
|
|
19
|
+
/**
|
|
20
|
+
* Base class helpers for the updating state of a component.
|
|
21
|
+
*/
|
|
22
|
+
function ReactComponent(props, context) {
|
|
23
|
+
this.props = props;
|
|
24
|
+
this.context = context;
|
|
34
25
|
}
|
|
35
26
|
|
|
36
27
|
/**
|
|
37
|
-
*
|
|
28
|
+
* Sets a subset of the state. Always use this to mutate
|
|
29
|
+
* state. You should treat `this.state` as immutable.
|
|
38
30
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* can be mutated using `setProps` or `replaceProps`.
|
|
31
|
+
* There is no guarantee that `this.state` will be immediately updated, so
|
|
32
|
+
* accessing `this.state` after calling this method may return the old value.
|
|
42
33
|
*
|
|
43
|
-
*
|
|
34
|
+
* There is no guarantee that calls to `setState` will run synchronously,
|
|
35
|
+
* as they may eventually be batched together. You can provide an optional
|
|
36
|
+
* callback that will be executed when the call to setState is actually
|
|
37
|
+
* completed.
|
|
44
38
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
39
|
+
* When a function is provided to setState, it will be called at some point in
|
|
40
|
+
* the future (not synchronously). It will be called with the up to date
|
|
41
|
+
* component arguments (state, props, context). These values can be different
|
|
42
|
+
* from this.* because your function may be called after receiveProps but before
|
|
43
|
+
* shouldComponentUpdate, and this new state, props, and context will not yet be
|
|
44
|
+
* assigned to this.
|
|
47
45
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
46
|
+
* @param {object|function} partialState Next partial state or function to
|
|
47
|
+
* produce next partial state to be merged with current state.
|
|
48
|
+
* @param {?function} callback Called after state is updated.
|
|
49
|
+
* @final
|
|
50
|
+
* @protected
|
|
51
|
+
*/
|
|
52
|
+
ReactComponent.prototype.setState = function(partialState, callback) {
|
|
53
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
54
|
+
typeof partialState === 'object' ||
|
|
55
|
+
typeof partialState === 'function' ||
|
|
56
|
+
partialState == null,
|
|
57
|
+
'setState(...): takes an object of state variables to update or a ' +
|
|
58
|
+
'function which returns an object of state variables.'
|
|
59
|
+
) : invariant(typeof partialState === 'object' ||
|
|
60
|
+
typeof partialState === 'function' ||
|
|
61
|
+
partialState == null));
|
|
62
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
63
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
64
|
+
partialState != null,
|
|
65
|
+
'setState(...): You passed an undefined or null state object; ' +
|
|
66
|
+
'instead, use forceUpdate().'
|
|
67
|
+
) : null);
|
|
68
|
+
}
|
|
69
|
+
ReactUpdateQueue.enqueueSetState(this, partialState);
|
|
70
|
+
if (callback) {
|
|
71
|
+
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Forces an update. This should only be invoked when it is known with
|
|
77
|
+
* certainty that we are **not** in a DOM transaction.
|
|
50
78
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
79
|
+
* You may want to call this when you know that some deeper aspect of the
|
|
80
|
+
* component's state has changed but `setState` was not called.
|
|
53
81
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* being the child of a component, which means having a DOM representation that
|
|
57
|
-
* is a child of the DOM representation of that component.
|
|
82
|
+
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
83
|
+
* `componentWillUpdate` and `componentDidUpdate`.
|
|
58
84
|
*
|
|
59
|
-
* @
|
|
85
|
+
* @param {?function} callback Called after update is complete.
|
|
86
|
+
* @final
|
|
87
|
+
* @protected
|
|
60
88
|
*/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*
|
|
68
|
-
* @internal
|
|
69
|
-
*/
|
|
70
|
-
BackendIDOperations: null,
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Base functionality for every ReactComponent constructor. Mixed into the
|
|
74
|
-
* `ReactComponent` prototype, but exposed statically for easy access.
|
|
75
|
-
*
|
|
76
|
-
* @lends {ReactComponent.prototype}
|
|
77
|
-
*/
|
|
78
|
-
Mixin: {
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Base constructor for all React components.
|
|
82
|
-
*
|
|
83
|
-
* Subclasses that override this method should make sure to invoke
|
|
84
|
-
* `ReactComponent.Mixin.construct.call(this, ...)`.
|
|
85
|
-
*
|
|
86
|
-
* @param {ReactElement} element
|
|
87
|
-
* @internal
|
|
88
|
-
*/
|
|
89
|
-
construct: function(element) {
|
|
90
|
-
// We keep the old element and a reference to the pending element
|
|
91
|
-
// to track updates.
|
|
92
|
-
this._currentElement = element;
|
|
93
|
-
// These two fields are used by the DOM and ART diffing algorithms
|
|
94
|
-
// respectively. Instead of using expandos on components, we should be
|
|
95
|
-
// storing the state needed by the diffing algorithms elsewhere.
|
|
96
|
-
this._mountIndex = 0;
|
|
97
|
-
this._mountImage = null;
|
|
98
|
-
},
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Initializes the component, renders markup, and registers event listeners.
|
|
102
|
-
*
|
|
103
|
-
* NOTE: This does not insert any nodes into the DOM.
|
|
104
|
-
*
|
|
105
|
-
* Subclasses that override this method should make sure to invoke
|
|
106
|
-
* `ReactComponent.Mixin.mountComponent.call(this, ...)`.
|
|
107
|
-
*
|
|
108
|
-
* @param {string} rootID DOM ID of the root node.
|
|
109
|
-
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
110
|
-
* @return {?string} Rendered markup to be inserted into the DOM.
|
|
111
|
-
* @internal
|
|
112
|
-
*/
|
|
113
|
-
mountComponent: function(rootID, transaction, context) {
|
|
114
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
115
|
-
ReactElementValidator.checkAndWarnForMutatedProps(this._currentElement);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
var ref = this._currentElement.ref;
|
|
119
|
-
if (ref != null) {
|
|
120
|
-
var owner = this._currentElement._owner;
|
|
121
|
-
attachRef(ref, this, owner);
|
|
122
|
-
}
|
|
123
|
-
// Effectively: return '';
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Releases any resources allocated by `mountComponent`.
|
|
128
|
-
*
|
|
129
|
-
* NOTE: This does not remove any nodes from the DOM.
|
|
130
|
-
*
|
|
131
|
-
* Subclasses that override this method should make sure to invoke
|
|
132
|
-
* `ReactComponent.Mixin.unmountComponent.call(this)`.
|
|
133
|
-
*
|
|
134
|
-
* @internal
|
|
135
|
-
*/
|
|
136
|
-
unmountComponent: function() {
|
|
137
|
-
var ref = this._currentElement.ref;
|
|
138
|
-
if (ref != null) {
|
|
139
|
-
detachRef(ref, this, this._currentElement._owner);
|
|
140
|
-
}
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Updates the component's currently mounted representation.
|
|
145
|
-
*
|
|
146
|
-
* @param {ReactReconcileTransaction} transaction
|
|
147
|
-
* @param {object} prevElement
|
|
148
|
-
* @param {object} nextElement
|
|
149
|
-
* @internal
|
|
150
|
-
*/
|
|
151
|
-
updateComponent: function(transaction, prevElement, nextElement, context) {
|
|
152
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
153
|
-
ReactElementValidator.checkAndWarnForMutatedProps(nextElement);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// If either the owner or a `ref` has changed, make sure the newest owner
|
|
157
|
-
// has stored a reference to `this`, and the previous owner (if different)
|
|
158
|
-
// has forgotten the reference to `this`. We use the element instead
|
|
159
|
-
// of the public this.props because the post processing cannot determine
|
|
160
|
-
// a ref. The ref conceptually lives on the element.
|
|
161
|
-
|
|
162
|
-
// TODO: Should this even be possible? The owner cannot change because
|
|
163
|
-
// it's forbidden by shouldUpdateReactComponent. The ref can change
|
|
164
|
-
// if you swap the keys of but not the refs. Reconsider where this check
|
|
165
|
-
// is made. It probably belongs where the key checking and
|
|
166
|
-
// instantiateReactComponent is done.
|
|
89
|
+
ReactComponent.prototype.forceUpdate = function(callback) {
|
|
90
|
+
ReactUpdateQueue.enqueueForceUpdate(this);
|
|
91
|
+
if (callback) {
|
|
92
|
+
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
167
95
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Deprecated APIs. These APIs used to exist on classic React classes but since
|
|
98
|
+
* we would like to deprecate them, we're not going to move them over to this
|
|
99
|
+
* modern base class. Instead, we define a getter that warns if it's accessed.
|
|
100
|
+
*/
|
|
101
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
102
|
+
var deprecatedAPIs = {
|
|
103
|
+
getDOMNode: 'getDOMNode',
|
|
104
|
+
isMounted: 'isMounted',
|
|
105
|
+
replaceState: 'replaceState',
|
|
106
|
+
setProps: 'setProps'
|
|
107
|
+
};
|
|
108
|
+
var defineDeprecationWarning = function(methodName, displayName) {
|
|
109
|
+
try {
|
|
110
|
+
Object.defineProperty(ReactComponent.prototype, methodName, {
|
|
111
|
+
get: function() {
|
|
112
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
113
|
+
false,
|
|
114
|
+
'%s(...) is deprecated in plain JavaScript React classes.',
|
|
115
|
+
displayName
|
|
116
|
+
) : null);
|
|
117
|
+
return undefined;
|
|
176
118
|
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
* @return {?ReactComponent} the actual sibling Component.
|
|
186
|
-
* @internal
|
|
187
|
-
*/
|
|
188
|
-
getPublicInstance: function() {
|
|
189
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
190
|
-
false,
|
|
191
|
-
'getPublicInstance should never be called on the base class. It must ' +
|
|
192
|
-
'be overridden.'
|
|
193
|
-
) : invariant(false));
|
|
119
|
+
});
|
|
120
|
+
} catch (x) {
|
|
121
|
+
// IE will fail on defineProperty (es5-shim/sham too)
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
for (var fnName in deprecatedAPIs) {
|
|
125
|
+
if (deprecatedAPIs.hasOwnProperty(fnName)) {
|
|
126
|
+
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
|
|
194
127
|
}
|
|
195
128
|
}
|
|
196
|
-
}
|
|
129
|
+
}
|
|
197
130
|
|
|
198
131
|
module.exports = ReactComponent;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2013-
|
|
2
|
+
* Copyright 2013-2015, Facebook, Inc.
|
|
3
3
|
* All rights reserved.
|
|
4
4
|
*
|
|
5
5
|
* This source code is licensed under the BSD-style license found in the
|
|
@@ -11,21 +11,23 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var ReactComponent = require("./ReactComponent");
|
|
15
14
|
var ReactComponentEnvironment = require("./ReactComponentEnvironment");
|
|
16
15
|
var ReactContext = require("./ReactContext");
|
|
17
16
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
18
17
|
var ReactElement = require("./ReactElement");
|
|
18
|
+
var ReactElementValidator = require("./ReactElementValidator");
|
|
19
19
|
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
20
|
+
var ReactLifeCycle = require("./ReactLifeCycle");
|
|
21
|
+
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
20
22
|
var ReactPerf = require("./ReactPerf");
|
|
21
23
|
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
22
24
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
25
|
+
var ReactReconciler = require("./ReactReconciler");
|
|
23
26
|
var ReactUpdates = require("./ReactUpdates");
|
|
24
27
|
|
|
25
28
|
var assign = require("./Object.assign");
|
|
26
29
|
var emptyObject = require("./emptyObject");
|
|
27
30
|
var invariant = require("./invariant");
|
|
28
|
-
var keyMirror = require("./keyMirror");
|
|
29
31
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
30
32
|
var warning = require("./warning");
|
|
31
33
|
|
|
@@ -40,63 +42,32 @@ function getDeclarationErrorAddendum(component) {
|
|
|
40
42
|
return '';
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
function validateLifeCycleOnReplaceState(instance) {
|
|
44
|
-
var compositeLifeCycleState = instance._compositeLifeCycleState;
|
|
45
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
46
|
-
ReactCurrentOwner.current == null,
|
|
47
|
-
'replaceState(...): Cannot update during an existing state transition ' +
|
|
48
|
-
'(such as within `render`). Render methods should be a pure function ' +
|
|
49
|
-
'of props and state.'
|
|
50
|
-
) : invariant(ReactCurrentOwner.current == null));
|
|
51
|
-
("production" !== process.env.NODE_ENV ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
|
|
52
|
-
'replaceState(...): Cannot update while unmounting component. This ' +
|
|
53
|
-
'usually means you called setState() on an unmounted component.'
|
|
54
|
-
) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
45
|
/**
|
|
58
|
-
*
|
|
59
|
-
* `this._compositeLifeCycleState` (which can be null).
|
|
46
|
+
* ------------------ The Life-Cycle of a Composite Component ------------------
|
|
60
47
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
48
|
+
* - constructor: Initialization of state. The instance is now retained.
|
|
49
|
+
* - componentWillMount
|
|
50
|
+
* - render
|
|
51
|
+
* - [children's constructors]
|
|
52
|
+
* - [children's componentWillMount and render]
|
|
53
|
+
* - [children's componentDidMount]
|
|
54
|
+
* - componentDidMount
|
|
65
55
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
56
|
+
* Update Phases:
|
|
57
|
+
* - componentWillReceiveProps (only called if parent updated)
|
|
58
|
+
* - shouldComponentUpdate
|
|
59
|
+
* - componentWillUpdate
|
|
60
|
+
* - render
|
|
61
|
+
* - [children's constructors or receive props phases]
|
|
62
|
+
* - componentDidUpdate
|
|
68
63
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* | 0--|MOUNTING|-0-|RECEIVE|-0-| UN |--->0 |
|
|
76
|
-
* | | | |PROPS | |MOUNTING| |
|
|
77
|
-
* | | | | | | | |
|
|
78
|
-
* | | | | | | | |
|
|
79
|
-
* | +--------+ +-------+ +--------+ |
|
|
80
|
-
* | | | |
|
|
81
|
-
* +-------+---------------------------------+--------+
|
|
64
|
+
* - componentWillUnmount
|
|
65
|
+
* - [children's componentWillUnmount]
|
|
66
|
+
* - [children destroyed]
|
|
67
|
+
* - (destroyed): The instance is now blank, released by React and ready for GC.
|
|
68
|
+
*
|
|
69
|
+
* -----------------------------------------------------------------------------
|
|
82
70
|
*/
|
|
83
|
-
var CompositeLifeCycle = keyMirror({
|
|
84
|
-
/**
|
|
85
|
-
* Components in the process of being mounted respond to state changes
|
|
86
|
-
* differently.
|
|
87
|
-
*/
|
|
88
|
-
MOUNTING: null,
|
|
89
|
-
/**
|
|
90
|
-
* Components in the process of being unmounted are guarded against state
|
|
91
|
-
* changes.
|
|
92
|
-
*/
|
|
93
|
-
UNMOUNTING: null,
|
|
94
|
-
/**
|
|
95
|
-
* Components that are mounted and receiving new props respond to state
|
|
96
|
-
* changes differently.
|
|
97
|
-
*/
|
|
98
|
-
RECEIVING_PROPS: null
|
|
99
|
-
});
|
|
100
71
|
|
|
101
72
|
/**
|
|
102
73
|
* An incrementing ID assigned to each component when it is mounted. This is
|
|
@@ -109,8 +80,7 @@ var nextMountID = 1;
|
|
|
109
80
|
/**
|
|
110
81
|
* @lends {ReactCompositeComponent.prototype}
|
|
111
82
|
*/
|
|
112
|
-
var ReactCompositeComponentMixin =
|
|
113
|
-
ReactComponent.Mixin, {
|
|
83
|
+
var ReactCompositeComponentMixin = {
|
|
114
84
|
|
|
115
85
|
/**
|
|
116
86
|
* Base constructor for all composite component.
|
|
@@ -120,42 +90,26 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
120
90
|
* @internal
|
|
121
91
|
*/
|
|
122
92
|
construct: function(element) {
|
|
93
|
+
this._currentElement = element;
|
|
123
94
|
this._rootNodeID = null;
|
|
95
|
+
this._instance = null;
|
|
124
96
|
|
|
125
|
-
|
|
126
|
-
this._instance.state = null;
|
|
127
|
-
this._instance.context = null;
|
|
128
|
-
this._instance.refs = emptyObject;
|
|
129
|
-
|
|
97
|
+
// See ReactUpdateQueue
|
|
130
98
|
this._pendingElement = null;
|
|
131
|
-
this.
|
|
132
|
-
this.
|
|
99
|
+
this._pendingStateQueue = null;
|
|
100
|
+
this._pendingReplaceState = false;
|
|
133
101
|
this._pendingForceUpdate = false;
|
|
134
|
-
this._compositeLifeCycleState = null;
|
|
135
102
|
|
|
136
103
|
this._renderedComponent = null;
|
|
137
104
|
|
|
138
|
-
// Children can be either an array or more than one argument
|
|
139
|
-
ReactComponent.Mixin.construct.apply(this, arguments);
|
|
140
|
-
|
|
141
105
|
this._context = null;
|
|
142
106
|
this._mountOrder = 0;
|
|
143
107
|
this._isTopLevel = false;
|
|
144
108
|
|
|
145
|
-
// See ReactUpdates.
|
|
109
|
+
// See ReactUpdates and ReactUpdateQueue.
|
|
146
110
|
this._pendingCallbacks = null;
|
|
147
111
|
},
|
|
148
112
|
|
|
149
|
-
/**
|
|
150
|
-
* Checks whether or not this composite component is mounted.
|
|
151
|
-
* @return {boolean} True if mounted, false otherwise.
|
|
152
|
-
* @protected
|
|
153
|
-
* @final
|
|
154
|
-
*/
|
|
155
|
-
isMounted: function() {
|
|
156
|
-
return this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;
|
|
157
|
-
},
|
|
158
|
-
|
|
159
113
|
/**
|
|
160
114
|
* Initializes the component, renders markup, and registers event listeners.
|
|
161
115
|
*
|
|
@@ -166,39 +120,35 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
166
120
|
* @internal
|
|
167
121
|
*/
|
|
168
122
|
mountComponent: function(rootID, transaction, context) {
|
|
169
|
-
ReactComponent.Mixin.mountComponent.call(
|
|
170
|
-
this,
|
|
171
|
-
rootID,
|
|
172
|
-
transaction,
|
|
173
|
-
context
|
|
174
|
-
);
|
|
175
|
-
|
|
176
123
|
this._context = context;
|
|
177
124
|
this._mountOrder = nextMountID++;
|
|
178
125
|
this._rootNodeID = rootID;
|
|
179
126
|
|
|
180
|
-
var
|
|
127
|
+
var publicProps = this._processProps(this._currentElement.props);
|
|
128
|
+
var publicContext = this._processContext(this._currentElement._context);
|
|
129
|
+
|
|
130
|
+
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
131
|
+
this._currentElement
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Initialize the public class
|
|
135
|
+
var inst = new Component(publicProps, publicContext);
|
|
136
|
+
// These should be set up in the constructor, but as a convenience for
|
|
137
|
+
// simpler class abstractions, we set them up after the fact.
|
|
138
|
+
inst.props = publicProps;
|
|
139
|
+
inst.context = publicContext;
|
|
140
|
+
inst.refs = emptyObject;
|
|
141
|
+
|
|
142
|
+
this._instance = inst;
|
|
181
143
|
|
|
182
144
|
// Store a reference from the instance back to the internal representation
|
|
183
145
|
ReactInstanceMap.set(inst, this);
|
|
184
146
|
|
|
185
|
-
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
|
186
|
-
|
|
187
|
-
inst.context = this._processContext(this._currentElement._context);
|
|
188
147
|
if ("production" !== process.env.NODE_ENV) {
|
|
189
148
|
this._warnIfContextsDiffer(this._currentElement._context, context);
|
|
190
149
|
}
|
|
191
|
-
inst.props = this._processProps(this._currentElement.props);
|
|
192
150
|
|
|
193
|
-
var initialState = inst.getInitialState ? inst.getInitialState() : null;
|
|
194
151
|
if ("production" !== process.env.NODE_ENV) {
|
|
195
|
-
// We allow auto-mocks to proceed as if they're returning null.
|
|
196
|
-
if (typeof initialState === 'undefined' &&
|
|
197
|
-
inst.getInitialState._isMockFunction) {
|
|
198
|
-
// This is probably bad practice. Consider warning here and
|
|
199
|
-
// deprecating this convenience.
|
|
200
|
-
initialState = null;
|
|
201
|
-
}
|
|
202
152
|
// Since plain JS classes are defined without any special initialization
|
|
203
153
|
// logic, we can not catch common errors early. Therefore, we have to
|
|
204
154
|
// catch them here, at initialization time, instead.
|
|
@@ -210,14 +160,6 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
210
160
|
'Did you mean to define a state property instead?',
|
|
211
161
|
this.getName() || 'a component'
|
|
212
162
|
) : null);
|
|
213
|
-
("production" !== process.env.NODE_ENV ? warning(
|
|
214
|
-
!inst.componentWillMount ||
|
|
215
|
-
inst.componentWillMount.isReactClassApproved,
|
|
216
|
-
'componentWillMount was defined on %s, a plain JavaScript class. ' +
|
|
217
|
-
'This is only supported for classes created using React.createClass. ' +
|
|
218
|
-
'Did you mean to define a constructor instead?',
|
|
219
|
-
this.getName() || 'a component'
|
|
220
|
-
) : null);
|
|
221
163
|
("production" !== process.env.NODE_ENV ? warning(
|
|
222
164
|
!inst.propTypes,
|
|
223
165
|
'propTypes was defined as an instance property on %s. Use a static ' +
|
|
@@ -239,35 +181,47 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
239
181
|
(this.getName() || 'A component')
|
|
240
182
|
) : null);
|
|
241
183
|
}
|
|
184
|
+
|
|
185
|
+
var initialState = inst.state;
|
|
186
|
+
if (initialState === undefined) {
|
|
187
|
+
inst.state = initialState = null;
|
|
188
|
+
}
|
|
242
189
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
243
190
|
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
244
|
-
'%s.
|
|
191
|
+
'%s.state: must be set to an object or null',
|
|
245
192
|
this.getName() || 'ReactCompositeComponent'
|
|
246
193
|
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
247
|
-
inst.state = initialState;
|
|
248
194
|
|
|
249
|
-
this.
|
|
195
|
+
this._pendingStateQueue = null;
|
|
196
|
+
this._pendingReplaceState = false;
|
|
250
197
|
this._pendingForceUpdate = false;
|
|
251
198
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
199
|
+
var renderedElement;
|
|
200
|
+
|
|
201
|
+
var previouslyMounting = ReactLifeCycle.currentlyMountingInstance;
|
|
202
|
+
ReactLifeCycle.currentlyMountingInstance = this;
|
|
203
|
+
try {
|
|
204
|
+
if (inst.componentWillMount) {
|
|
205
|
+
inst.componentWillMount();
|
|
206
|
+
// When mounting, calls to `setState` by `componentWillMount` will set
|
|
207
|
+
// `this._pendingStateQueue` without triggering a re-render.
|
|
208
|
+
if (this._pendingStateQueue) {
|
|
209
|
+
inst.state = this._processPendingState(inst.props, inst.context);
|
|
210
|
+
}
|
|
259
211
|
}
|
|
212
|
+
|
|
213
|
+
renderedElement = this._renderValidatedComponent();
|
|
214
|
+
} finally {
|
|
215
|
+
ReactLifeCycle.currentlyMountingInstance = previouslyMounting;
|
|
260
216
|
}
|
|
261
217
|
|
|
262
|
-
var renderedElement = this._renderValidatedComponent();
|
|
263
218
|
this._renderedComponent = this._instantiateReactComponent(
|
|
264
219
|
renderedElement,
|
|
265
220
|
this._currentElement.type // The wrapping type
|
|
266
221
|
);
|
|
267
222
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
var markup = this._renderedComponent.mountComponent(
|
|
223
|
+
var markup = ReactReconciler.mountComponent(
|
|
224
|
+
this._renderedComponent,
|
|
271
225
|
rootID,
|
|
272
226
|
transaction,
|
|
273
227
|
this._processChildContext(context)
|
|
@@ -275,6 +229,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
275
229
|
if (inst.componentDidMount) {
|
|
276
230
|
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
|
277
231
|
}
|
|
232
|
+
|
|
278
233
|
return markup;
|
|
279
234
|
},
|
|
280
235
|
|
|
@@ -287,25 +242,28 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
287
242
|
unmountComponent: function() {
|
|
288
243
|
var inst = this._instance;
|
|
289
244
|
|
|
290
|
-
this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
|
|
291
245
|
if (inst.componentWillUnmount) {
|
|
292
|
-
|
|
246
|
+
var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance;
|
|
247
|
+
ReactLifeCycle.currentlyUnmountingInstance = this;
|
|
248
|
+
try {
|
|
249
|
+
inst.componentWillUnmount();
|
|
250
|
+
} finally {
|
|
251
|
+
ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting;
|
|
252
|
+
}
|
|
293
253
|
}
|
|
294
|
-
this._compositeLifeCycleState = null;
|
|
295
254
|
|
|
296
|
-
this._renderedComponent
|
|
255
|
+
ReactReconciler.unmountComponent(this._renderedComponent);
|
|
297
256
|
this._renderedComponent = null;
|
|
298
257
|
|
|
299
258
|
// Reset pending fields
|
|
300
|
-
this.
|
|
259
|
+
this._pendingStateQueue = null;
|
|
260
|
+
this._pendingReplaceState = false;
|
|
301
261
|
this._pendingForceUpdate = false;
|
|
302
262
|
this._pendingCallbacks = null;
|
|
303
263
|
this._pendingElement = null;
|
|
304
264
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
ReactComponentEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
308
|
-
|
|
265
|
+
// These fields do not really need to be reset since this object is no
|
|
266
|
+
// longer accessible.
|
|
309
267
|
this._context = null;
|
|
310
268
|
this._rootNodeID = null;
|
|
311
269
|
|
|
@@ -321,50 +279,6 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
321
279
|
// TODO: inst.context = null;
|
|
322
280
|
},
|
|
323
281
|
|
|
324
|
-
/**
|
|
325
|
-
* Sets a subset of the props.
|
|
326
|
-
*
|
|
327
|
-
* @param {object} partialProps Subset of the next props.
|
|
328
|
-
* @param {?function} callback Called after props are updated.
|
|
329
|
-
* @final
|
|
330
|
-
* @public
|
|
331
|
-
*/
|
|
332
|
-
setProps: function(partialProps, callback) {
|
|
333
|
-
// Merge with the pending element if it exists, otherwise with existing
|
|
334
|
-
// element props.
|
|
335
|
-
var element = this._pendingElement || this._currentElement;
|
|
336
|
-
this.replaceProps(
|
|
337
|
-
assign({}, element.props, partialProps),
|
|
338
|
-
callback
|
|
339
|
-
);
|
|
340
|
-
},
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Replaces all of the props.
|
|
344
|
-
*
|
|
345
|
-
* @param {object} props New props.
|
|
346
|
-
* @param {?function} callback Called after props are updated.
|
|
347
|
-
* @final
|
|
348
|
-
* @public
|
|
349
|
-
*/
|
|
350
|
-
replaceProps: function(props, callback) {
|
|
351
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
352
|
-
this._isTopLevel,
|
|
353
|
-
'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
|
|
354
|
-
'component with a parent. This is an anti-pattern since props will ' +
|
|
355
|
-
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
356
|
-
'`render` method to pass the correct value as props to the component ' +
|
|
357
|
-
'where it is created.'
|
|
358
|
-
) : invariant(this._isTopLevel));
|
|
359
|
-
// This is a deoptimized path. We optimize for always having an element.
|
|
360
|
-
// This creates an extra internal element.
|
|
361
|
-
this._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
362
|
-
this._pendingElement || this._currentElement,
|
|
363
|
-
props
|
|
364
|
-
);
|
|
365
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
366
|
-
},
|
|
367
|
-
|
|
368
282
|
/**
|
|
369
283
|
* Schedule a partial update to the props. Only used for internal testing.
|
|
370
284
|
*
|
|
@@ -384,89 +298,22 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
384
298
|
ReactUpdates.enqueueUpdate(this, callback);
|
|
385
299
|
},
|
|
386
300
|
|
|
387
|
-
/**
|
|
388
|
-
* Sets a subset of the state. This only exists because _pendingState is
|
|
389
|
-
* internal. This provides a merging strategy that is not available to deep
|
|
390
|
-
* properties which is confusing. TODO: Expose pendingState or don't use it
|
|
391
|
-
* during the merge.
|
|
392
|
-
*
|
|
393
|
-
* @param {object} partialState Next partial state to be merged with state.
|
|
394
|
-
* @param {?function} callback Called after state is updated.
|
|
395
|
-
* @final
|
|
396
|
-
* @protected
|
|
397
|
-
*/
|
|
398
|
-
setState: function(partialState, callback) {
|
|
399
|
-
// Merge with `_pendingState` if it exists, otherwise with existing state.
|
|
400
|
-
this.replaceState(
|
|
401
|
-
assign({}, this._pendingState || this._instance.state, partialState),
|
|
402
|
-
callback
|
|
403
|
-
);
|
|
404
|
-
},
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Replaces all of the state. Always use this or `setState` to mutate state.
|
|
408
|
-
* You should treat `this.state` as immutable.
|
|
409
|
-
*
|
|
410
|
-
* There is no guarantee that `this.state` will be immediately updated, so
|
|
411
|
-
* accessing `this.state` after calling this method may return the old value.
|
|
412
|
-
*
|
|
413
|
-
* @param {object} completeState Next state.
|
|
414
|
-
* @param {?function} callback Called after state is updated.
|
|
415
|
-
* @final
|
|
416
|
-
* @protected
|
|
417
|
-
*/
|
|
418
|
-
replaceState: function(completeState, callback) {
|
|
419
|
-
validateLifeCycleOnReplaceState(this);
|
|
420
|
-
this._pendingState = completeState;
|
|
421
|
-
if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) {
|
|
422
|
-
// If we're in a componentWillMount handler, don't enqueue a rerender
|
|
423
|
-
// because ReactUpdates assumes we're in a browser context (which is wrong
|
|
424
|
-
// for server rendering) and we're about to do a render anyway.
|
|
425
|
-
// TODO: The callback here is ignored when setState is called from
|
|
426
|
-
// componentWillMount. Either fix it or disallow doing so completely in
|
|
427
|
-
// favor of getInitialState.
|
|
428
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
429
|
-
}
|
|
430
|
-
},
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* Forces an update. This should only be invoked when it is known with
|
|
434
|
-
* certainty that we are **not** in a DOM transaction.
|
|
435
|
-
*
|
|
436
|
-
* You may want to call this when you know that some deeper aspect of the
|
|
437
|
-
* component's state has changed but `setState` was not called.
|
|
438
|
-
*
|
|
439
|
-
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
440
|
-
* `componentWillUpdate` and `componentDidUpdate`.
|
|
441
|
-
*
|
|
442
|
-
* @param {?function} callback Called after update is complete.isM
|
|
443
|
-
* @final
|
|
444
|
-
* @protected
|
|
445
|
-
*/
|
|
446
|
-
forceUpdate: function(callback) {
|
|
447
|
-
var compositeLifeCycleState = this._compositeLifeCycleState;
|
|
448
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
449
|
-
compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
|
|
450
|
-
compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
|
|
451
|
-
'forceUpdate(...): Cannot force an update while unmounting component ' +
|
|
452
|
-
'or during an existing state transition (such as within `render`).'
|
|
453
|
-
) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
|
|
454
|
-
compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
|
|
455
|
-
this._pendingForceUpdate = true;
|
|
456
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
457
|
-
},
|
|
458
|
-
|
|
459
301
|
/**
|
|
460
302
|
* Filters the context object to only contain keys specified in
|
|
461
|
-
* `contextTypes
|
|
303
|
+
* `contextTypes`
|
|
462
304
|
*
|
|
463
305
|
* @param {object} context
|
|
464
306
|
* @return {?object}
|
|
465
307
|
* @private
|
|
466
308
|
*/
|
|
467
|
-
|
|
309
|
+
_maskContext: function(context) {
|
|
468
310
|
var maskedContext = null;
|
|
469
|
-
|
|
311
|
+
// This really should be getting the component class for the element,
|
|
312
|
+
// but we know that we're not going to need it for built-ins.
|
|
313
|
+
if (typeof this._currentElement.type === 'string') {
|
|
314
|
+
return emptyObject;
|
|
315
|
+
}
|
|
316
|
+
var contextTypes = this._currentElement.type.contextTypes;
|
|
470
317
|
if (!contextTypes) {
|
|
471
318
|
return emptyObject;
|
|
472
319
|
}
|
|
@@ -474,12 +321,30 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
474
321
|
for (var contextName in contextTypes) {
|
|
475
322
|
maskedContext[contextName] = context[contextName];
|
|
476
323
|
}
|
|
324
|
+
return maskedContext;
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Filters the context object to only contain keys specified in
|
|
329
|
+
* `contextTypes`, and asserts that they are valid.
|
|
330
|
+
*
|
|
331
|
+
* @param {object} context
|
|
332
|
+
* @return {?object}
|
|
333
|
+
* @private
|
|
334
|
+
*/
|
|
335
|
+
_processContext: function(context) {
|
|
336
|
+
var maskedContext = this._maskContext(context);
|
|
477
337
|
if ("production" !== process.env.NODE_ENV) {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
maskedContext,
|
|
481
|
-
ReactPropTypeLocations.context
|
|
338
|
+
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
339
|
+
this._currentElement
|
|
482
340
|
);
|
|
341
|
+
if (Component.contextTypes) {
|
|
342
|
+
this._checkPropTypes(
|
|
343
|
+
Component.contextTypes,
|
|
344
|
+
maskedContext,
|
|
345
|
+
ReactPropTypeLocations.context
|
|
346
|
+
);
|
|
347
|
+
}
|
|
483
348
|
}
|
|
484
349
|
return maskedContext;
|
|
485
350
|
},
|
|
@@ -530,10 +395,15 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
530
395
|
*/
|
|
531
396
|
_processProps: function(newProps) {
|
|
532
397
|
if ("production" !== process.env.NODE_ENV) {
|
|
533
|
-
var
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
398
|
+
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
399
|
+
this._currentElement
|
|
400
|
+
);
|
|
401
|
+
if (Component.propTypes) {
|
|
402
|
+
this._checkPropTypes(
|
|
403
|
+
Component.propTypes,
|
|
404
|
+
newProps,
|
|
405
|
+
ReactPropTypeLocations.prop
|
|
406
|
+
);
|
|
537
407
|
}
|
|
538
408
|
}
|
|
539
409
|
return newProps;
|
|
@@ -574,74 +444,75 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
574
444
|
// React.render calls, so I'm abstracting it away into
|
|
575
445
|
// a function to minimize refactoring in the future
|
|
576
446
|
var addendum = getDeclarationErrorAddendum(this);
|
|
577
|
-
|
|
447
|
+
|
|
448
|
+
if (location === ReactPropTypeLocations.prop) {
|
|
449
|
+
// Preface gives us something to blacklist in warning module
|
|
450
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
451
|
+
false,
|
|
452
|
+
'Failed Composite propType: %s%s',
|
|
453
|
+
error.message,
|
|
454
|
+
addendum
|
|
455
|
+
) : null);
|
|
456
|
+
} else {
|
|
457
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
458
|
+
false,
|
|
459
|
+
'Failed Context Types: %s%s',
|
|
460
|
+
error.message,
|
|
461
|
+
addendum
|
|
462
|
+
) : null);
|
|
463
|
+
}
|
|
578
464
|
}
|
|
579
465
|
}
|
|
580
466
|
}
|
|
581
467
|
},
|
|
582
468
|
|
|
583
|
-
receiveComponent: function(nextElement, transaction,
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
// Since elements are immutable after the owner is rendered,
|
|
587
|
-
// we can do a cheap identity compare here to determine if this is a
|
|
588
|
-
// superfluous reconcile. It's possible for state to be mutable but such
|
|
589
|
-
// change should trigger an update of the owner which would recreate
|
|
590
|
-
// the element. We explicitly check for the existence of an owner since
|
|
591
|
-
// it's possible for an element created outside a composite to be
|
|
592
|
-
// deeply mutated and reused.
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
469
|
+
receiveComponent: function(nextElement, transaction, nextContext) {
|
|
470
|
+
var prevElement = this._currentElement;
|
|
471
|
+
var prevContext = this._context;
|
|
595
472
|
|
|
596
|
-
this._pendingElement =
|
|
597
|
-
|
|
598
|
-
this.
|
|
473
|
+
this._pendingElement = null;
|
|
474
|
+
|
|
475
|
+
this.updateComponent(
|
|
476
|
+
transaction,
|
|
477
|
+
prevElement,
|
|
478
|
+
nextElement,
|
|
479
|
+
prevContext,
|
|
480
|
+
nextContext
|
|
481
|
+
);
|
|
599
482
|
},
|
|
600
483
|
|
|
601
484
|
/**
|
|
602
|
-
* If any of `_pendingElement`, `
|
|
485
|
+
* If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
|
|
603
486
|
* is set, update the component.
|
|
604
487
|
*
|
|
605
488
|
* @param {ReactReconcileTransaction} transaction
|
|
606
489
|
* @internal
|
|
607
490
|
*/
|
|
608
491
|
performUpdateIfNecessary: function(transaction) {
|
|
609
|
-
var compositeLifeCycleState = this._compositeLifeCycleState;
|
|
610
|
-
// Do not trigger a state transition if we are in the middle of mounting or
|
|
611
|
-
// receiving props because both of those will already be doing this.
|
|
612
|
-
if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
|
|
613
|
-
compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
|
|
614
|
-
return;
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
if (this._pendingElement == null &&
|
|
618
|
-
this._pendingState == null &&
|
|
619
|
-
this._pendingContext == null &&
|
|
620
|
-
!this._pendingForceUpdate) {
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
var prevElement = this._currentElement;
|
|
625
|
-
var nextElement = prevElement;
|
|
626
492
|
if (this._pendingElement != null) {
|
|
627
|
-
|
|
628
|
-
|
|
493
|
+
ReactReconciler.receiveComponent(
|
|
494
|
+
this,
|
|
495
|
+
this._pendingElement || this._currentElement,
|
|
496
|
+
transaction,
|
|
497
|
+
this._context
|
|
498
|
+
);
|
|
629
499
|
}
|
|
630
500
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
501
|
+
if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
|
|
502
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
503
|
+
ReactElementValidator.checkAndWarnForMutatedProps(
|
|
504
|
+
this._currentElement
|
|
505
|
+
);
|
|
506
|
+
}
|
|
637
507
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
508
|
+
this.updateComponent(
|
|
509
|
+
transaction,
|
|
510
|
+
this._currentElement,
|
|
511
|
+
this._currentElement,
|
|
512
|
+
this._context,
|
|
513
|
+
this._context
|
|
514
|
+
);
|
|
515
|
+
}
|
|
645
516
|
},
|
|
646
517
|
|
|
647
518
|
/**
|
|
@@ -649,35 +520,22 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
649
520
|
* TODO: Remove this check when owner-context is removed
|
|
650
521
|
*/
|
|
651
522
|
_warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) {
|
|
652
|
-
|
|
523
|
+
ownerBasedContext = this._maskContext(ownerBasedContext);
|
|
524
|
+
parentBasedContext = this._maskContext(parentBasedContext);
|
|
653
525
|
var parentKeys = Object.keys(parentBasedContext).sort();
|
|
654
526
|
var displayName = this.getName() || 'ReactCompositeComponent';
|
|
655
|
-
|
|
656
|
-
|
|
527
|
+
for (var i = 0; i < parentKeys.length; i++) {
|
|
528
|
+
var key = parentKeys[i];
|
|
657
529
|
("production" !== process.env.NODE_ENV ? warning(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
'
|
|
661
|
-
'context (keys: %s) while mounting %s ' +
|
|
530
|
+
ownerBasedContext[key] === parentBasedContext[key],
|
|
531
|
+
'owner-based and parent-based contexts differ ' +
|
|
532
|
+
'(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
|
|
662
533
|
'(see: http://fb.me/react-context-by-parent)',
|
|
663
|
-
|
|
664
|
-
|
|
534
|
+
ownerBasedContext[key],
|
|
535
|
+
parentBasedContext[key],
|
|
536
|
+
key,
|
|
665
537
|
displayName
|
|
666
538
|
) : null);
|
|
667
|
-
} else {
|
|
668
|
-
for (var i = 0; i < parentKeys.length; i++) {
|
|
669
|
-
var key = parentKeys[i];
|
|
670
|
-
("production" !== process.env.NODE_ENV ? warning(
|
|
671
|
-
ownerBasedContext[key] === parentBasedContext[key],
|
|
672
|
-
'owner-based and parent-based contexts differ ' +
|
|
673
|
-
'(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
|
|
674
|
-
'(see: http://fb.me/react-context-by-parent)',
|
|
675
|
-
ownerBasedContext[key],
|
|
676
|
-
parentBasedContext[key],
|
|
677
|
-
key,
|
|
678
|
-
displayName
|
|
679
|
-
) : null);
|
|
680
|
-
}
|
|
681
539
|
}
|
|
682
540
|
},
|
|
683
541
|
|
|
@@ -703,22 +561,11 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
703
561
|
prevUnmaskedContext,
|
|
704
562
|
nextUnmaskedContext
|
|
705
563
|
) {
|
|
706
|
-
// Update refs regardless of what shouldComponentUpdate returns
|
|
707
|
-
ReactComponent.Mixin.updateComponent.call(
|
|
708
|
-
this,
|
|
709
|
-
transaction,
|
|
710
|
-
prevParentElement,
|
|
711
|
-
nextParentElement,
|
|
712
|
-
prevUnmaskedContext,
|
|
713
|
-
nextUnmaskedContext
|
|
714
|
-
);
|
|
715
|
-
|
|
716
564
|
var inst = this._instance;
|
|
717
565
|
|
|
718
|
-
var
|
|
719
|
-
var
|
|
720
|
-
|
|
721
|
-
var nextProps = prevProps;
|
|
566
|
+
var nextContext = inst.context;
|
|
567
|
+
var nextProps = inst.props;
|
|
568
|
+
|
|
722
569
|
// Distinguish between a props update versus a simple state update
|
|
723
570
|
if (prevParentElement !== nextParentElement) {
|
|
724
571
|
nextContext = this._processContext(nextParentElement._context);
|
|
@@ -726,20 +573,23 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
726
573
|
|
|
727
574
|
if ("production" !== process.env.NODE_ENV) {
|
|
728
575
|
if (nextUnmaskedContext != null) {
|
|
729
|
-
this._warnIfContextsDiffer(
|
|
576
|
+
this._warnIfContextsDiffer(
|
|
577
|
+
nextParentElement._context,
|
|
578
|
+
nextUnmaskedContext
|
|
579
|
+
);
|
|
730
580
|
}
|
|
731
581
|
}
|
|
732
582
|
|
|
733
|
-
|
|
583
|
+
// An update here will schedule an update but immediately set
|
|
584
|
+
// _pendingStateQueue which will ensure that any state updates gets
|
|
585
|
+
// immediately reconciled instead of waiting for the next batch.
|
|
586
|
+
|
|
734
587
|
if (inst.componentWillReceiveProps) {
|
|
735
588
|
inst.componentWillReceiveProps(nextProps, nextContext);
|
|
736
589
|
}
|
|
737
590
|
}
|
|
738
591
|
|
|
739
|
-
this.
|
|
740
|
-
|
|
741
|
-
var nextState = this._pendingState || inst.state;
|
|
742
|
-
this._pendingState = null;
|
|
592
|
+
var nextState = this._processPendingState(nextProps, nextContext);
|
|
743
593
|
|
|
744
594
|
var shouldUpdate =
|
|
745
595
|
this._pendingForceUpdate ||
|
|
@@ -747,16 +597,26 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
747
597
|
inst.shouldComponentUpdate(nextProps, nextState, nextContext);
|
|
748
598
|
|
|
749
599
|
if ("production" !== process.env.NODE_ENV) {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
600
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
601
|
+
typeof shouldUpdate !== 'undefined',
|
|
602
|
+
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
|
|
603
|
+
'boolean value. Make sure to return true or false.',
|
|
604
|
+
this.getName() || 'ReactCompositeComponent'
|
|
605
|
+
) : null);
|
|
757
606
|
}
|
|
758
607
|
|
|
759
|
-
if (
|
|
608
|
+
if (shouldUpdate) {
|
|
609
|
+
this._pendingForceUpdate = false;
|
|
610
|
+
// Will set `this.props`, `this.state` and `this.context`.
|
|
611
|
+
this._performComponentUpdate(
|
|
612
|
+
nextParentElement,
|
|
613
|
+
nextProps,
|
|
614
|
+
nextState,
|
|
615
|
+
nextContext,
|
|
616
|
+
transaction,
|
|
617
|
+
nextUnmaskedContext
|
|
618
|
+
);
|
|
619
|
+
} else {
|
|
760
620
|
// If it's determined that a component should not update, we still want
|
|
761
621
|
// to set props and state but we shortcut the rest of the update.
|
|
762
622
|
this._currentElement = nextParentElement;
|
|
@@ -764,19 +624,32 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
764
624
|
inst.props = nextProps;
|
|
765
625
|
inst.state = nextState;
|
|
766
626
|
inst.context = nextContext;
|
|
767
|
-
return;
|
|
768
627
|
}
|
|
628
|
+
},
|
|
769
629
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
this.
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
630
|
+
_processPendingState: function(props, context) {
|
|
631
|
+
var inst = this._instance;
|
|
632
|
+
var queue = this._pendingStateQueue;
|
|
633
|
+
var replace = this._pendingReplaceState;
|
|
634
|
+
this._pendingReplaceState = false;
|
|
635
|
+
this._pendingStateQueue = null;
|
|
636
|
+
|
|
637
|
+
if (!queue) {
|
|
638
|
+
return inst.state;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
var nextState = assign({}, replace ? queue[0] : inst.state);
|
|
642
|
+
for (var i = replace ? 1 : 0; i < queue.length; i++) {
|
|
643
|
+
var partial = queue[i];
|
|
644
|
+
assign(
|
|
645
|
+
nextState,
|
|
646
|
+
typeof partial === 'function' ?
|
|
647
|
+
partial.call(inst, nextState, props, context) :
|
|
648
|
+
partial
|
|
649
|
+
);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
return nextState;
|
|
780
653
|
},
|
|
781
654
|
|
|
782
655
|
/**
|
|
@@ -836,7 +709,8 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
836
709
|
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
837
710
|
var nextRenderedElement = this._renderValidatedComponent();
|
|
838
711
|
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
|
|
839
|
-
|
|
712
|
+
ReactReconciler.receiveComponent(
|
|
713
|
+
prevComponentInstance,
|
|
840
714
|
nextRenderedElement,
|
|
841
715
|
transaction,
|
|
842
716
|
this._processChildContext(context)
|
|
@@ -845,26 +719,34 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
845
719
|
// These two IDs are actually the same! But nothing should rely on that.
|
|
846
720
|
var thisID = this._rootNodeID;
|
|
847
721
|
var prevComponentID = prevComponentInstance._rootNodeID;
|
|
848
|
-
|
|
722
|
+
ReactReconciler.unmountComponent(prevComponentInstance);
|
|
849
723
|
|
|
850
724
|
this._renderedComponent = this._instantiateReactComponent(
|
|
851
725
|
nextRenderedElement,
|
|
852
726
|
this._currentElement.type
|
|
853
727
|
);
|
|
854
|
-
var nextMarkup =
|
|
728
|
+
var nextMarkup = ReactReconciler.mountComponent(
|
|
729
|
+
this._renderedComponent,
|
|
855
730
|
thisID,
|
|
856
731
|
transaction,
|
|
857
732
|
context
|
|
858
733
|
);
|
|
859
|
-
|
|
860
|
-
prevComponentID,
|
|
861
|
-
nextMarkup
|
|
862
|
-
);
|
|
734
|
+
this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup);
|
|
863
735
|
}
|
|
864
736
|
},
|
|
865
737
|
|
|
866
738
|
/**
|
|
867
|
-
* @
|
|
739
|
+
* @protected
|
|
740
|
+
*/
|
|
741
|
+
_replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) {
|
|
742
|
+
ReactComponentEnvironment.replaceNodeWithMarkupByID(
|
|
743
|
+
prevComponentID,
|
|
744
|
+
nextMarkup
|
|
745
|
+
);
|
|
746
|
+
},
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* @protected
|
|
868
750
|
*/
|
|
869
751
|
_renderValidatedComponentWithoutOwnerOrContext: function() {
|
|
870
752
|
var inst = this._instance;
|
|
@@ -892,7 +774,6 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
892
774
|
this._currentElement._context
|
|
893
775
|
);
|
|
894
776
|
ReactCurrentOwner.current = this;
|
|
895
|
-
var inst = this._instance;
|
|
896
777
|
try {
|
|
897
778
|
renderedComponent =
|
|
898
779
|
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
@@ -947,7 +828,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
947
828
|
*/
|
|
948
829
|
getName: function() {
|
|
949
830
|
var type = this._currentElement.type;
|
|
950
|
-
var constructor = this._instance.constructor;
|
|
831
|
+
var constructor = this._instance && this._instance.constructor;
|
|
951
832
|
return (
|
|
952
833
|
type.displayName || (constructor && constructor.displayName) ||
|
|
953
834
|
type.name || (constructor && constructor.name) ||
|
|
@@ -970,103 +851,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
970
851
|
// Stub
|
|
971
852
|
_instantiateReactComponent: null
|
|
972
853
|
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
var ShallowMixin = assign({},
|
|
976
|
-
ReactCompositeComponentMixin, {
|
|
977
|
-
|
|
978
|
-
/**
|
|
979
|
-
* Initializes the component, renders markup, and registers event listeners.
|
|
980
|
-
*
|
|
981
|
-
* @param {string} rootID DOM ID of the root node.
|
|
982
|
-
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
983
|
-
* @return {ReactElement} Shallow rendering of the component.
|
|
984
|
-
* @final
|
|
985
|
-
* @internal
|
|
986
|
-
*/
|
|
987
|
-
mountComponent: function(rootID, transaction, context) {
|
|
988
|
-
ReactComponent.Mixin.mountComponent.call(
|
|
989
|
-
this,
|
|
990
|
-
rootID,
|
|
991
|
-
transaction,
|
|
992
|
-
context
|
|
993
|
-
);
|
|
994
|
-
|
|
995
|
-
var inst = this._instance;
|
|
996
|
-
|
|
997
|
-
// Store a reference from the instance back to the internal representation
|
|
998
|
-
ReactInstanceMap.set(inst, this);
|
|
999
|
-
|
|
1000
|
-
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
|
1001
|
-
|
|
1002
|
-
// No context for shallow-mounted components.
|
|
1003
|
-
inst.props = this._processProps(this._currentElement.props);
|
|
1004
|
-
|
|
1005
|
-
var initialState = inst.getInitialState ? inst.getInitialState() : null;
|
|
1006
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
1007
|
-
// We allow auto-mocks to proceed as if they're returning null.
|
|
1008
|
-
if (typeof initialState === 'undefined' &&
|
|
1009
|
-
inst.getInitialState._isMockFunction) {
|
|
1010
|
-
// This is probably bad practice. Consider warning here and
|
|
1011
|
-
// deprecating this convenience.
|
|
1012
|
-
initialState = null;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
1016
|
-
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
1017
|
-
'%s.getInitialState(): must return an object or null',
|
|
1018
|
-
this.getName() || 'ReactCompositeComponent'
|
|
1019
|
-
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
1020
|
-
inst.state = initialState;
|
|
1021
|
-
|
|
1022
|
-
this._pendingState = null;
|
|
1023
|
-
this._pendingForceUpdate = false;
|
|
1024
|
-
|
|
1025
|
-
if (inst.componentWillMount) {
|
|
1026
|
-
inst.componentWillMount();
|
|
1027
|
-
// When mounting, calls to `setState` by `componentWillMount` will set
|
|
1028
|
-
// `this._pendingState` without triggering a re-render.
|
|
1029
|
-
if (this._pendingState) {
|
|
1030
|
-
inst.state = this._pendingState;
|
|
1031
|
-
this._pendingState = null;
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
// No recursive call to instantiateReactComponent for shallow rendering.
|
|
1036
|
-
this._renderedComponent =
|
|
1037
|
-
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
1038
|
-
|
|
1039
|
-
// Done with mounting, `setState` will now trigger UI changes.
|
|
1040
|
-
this._compositeLifeCycleState = null;
|
|
1041
|
-
|
|
1042
|
-
// No call to this._renderedComponent.mountComponent for shallow
|
|
1043
|
-
// rendering.
|
|
1044
|
-
|
|
1045
|
-
if (inst.componentDidMount) {
|
|
1046
|
-
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
return this._renderedComponent;
|
|
1050
|
-
},
|
|
1051
|
-
|
|
1052
|
-
/**
|
|
1053
|
-
* Call the component's `render` method and update the DOM accordingly.
|
|
1054
|
-
*
|
|
1055
|
-
* @param {ReactReconcileTransaction} transaction
|
|
1056
|
-
* @internal
|
|
1057
|
-
*/
|
|
1058
|
-
_updateRenderedComponent: function(transaction) {
|
|
1059
|
-
var prevComponentInstance = this._renderedComponent;
|
|
1060
|
-
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
1061
|
-
// Use the without-owner-or-context variant of _rVC below:
|
|
1062
|
-
var nextRenderedElement =
|
|
1063
|
-
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
1064
|
-
// This is a noop in shallow render
|
|
1065
|
-
shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement);
|
|
1066
|
-
this._renderedComponent = nextRenderedElement;
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
});
|
|
854
|
+
};
|
|
1070
855
|
|
|
1071
856
|
ReactPerf.measureMethods(
|
|
1072
857
|
ReactCompositeComponentMixin,
|
|
@@ -1080,11 +865,7 @@ ReactPerf.measureMethods(
|
|
|
1080
865
|
|
|
1081
866
|
var ReactCompositeComponent = {
|
|
1082
867
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
Mixin: ReactCompositeComponentMixin,
|
|
1086
|
-
|
|
1087
|
-
ShallowMixin: ShallowMixin
|
|
868
|
+
Mixin: ReactCompositeComponentMixin
|
|
1088
869
|
|
|
1089
870
|
};
|
|
1090
871
|
|