react 0.13.0-alpha.1 → 0.13.0-rc1
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 +1376 -596
- package/dist/react-with-addons.js +3256 -2363
- package/dist/react-with-addons.min.js +7 -7
- package/dist/react.js +3092 -2266
- package/dist/react.min.js +6 -7
- package/lib/AutoFocusMixin.js +2 -2
- package/lib/BeforeInputEventPlugin.js +5 -9
- package/lib/CSSCore.js +1 -1
- package/lib/CSSProperty.js +4 -2
- package/lib/CSSPropertyOperations.js +44 -17
- package/lib/CallbackQueue.js +3 -3
- package/lib/ChangeEventPlugin.js +2 -2
- package/lib/ClientReactRootIndex.js +2 -2
- package/lib/DOMChildrenOperations.js +10 -47
- package/lib/DOMProperty.js +2 -2
- package/lib/DOMPropertyOperations.js +11 -16
- package/lib/Danger.js +7 -6
- package/lib/DefaultEventPluginOrder.js +3 -3
- package/lib/EnterLeaveEventPlugin.js +2 -2
- package/lib/EventConstants.js +2 -2
- package/lib/EventListener.js +1 -1
- package/lib/EventPluginHub.js +10 -8
- package/lib/EventPluginRegistry.js +2 -2
- package/lib/EventPluginUtils.js +4 -4
- package/lib/EventPropagators.js +2 -2
- package/lib/ExecutionEnvironment.js +1 -1
- package/lib/FallbackCompositionState.js +7 -5
- package/lib/HTMLDOMPropertyConfig.js +22 -10
- package/lib/LinkedStateMixin.js +2 -2
- package/lib/LinkedValueUtils.js +4 -4
- package/lib/LocalEventTrapMixin.js +10 -3
- package/lib/MobileSafariClickEventPlugin.js +2 -2
- package/lib/Object.assign.js +2 -2
- package/lib/PooledClass.js +2 -2
- package/lib/React.js +9 -13
- package/lib/ReactBrowserComponentMixin.js +2 -2
- package/lib/ReactBrowserEventEmitter.js +4 -4
- package/lib/ReactCSSTransitionGroup.js +2 -2
- package/lib/ReactCSSTransitionGroupChild.js +12 -7
- package/lib/ReactChildReconciler.js +11 -7
- package/lib/ReactChildren.js +13 -10
- package/lib/ReactClass.js +161 -135
- package/lib/ReactComponent.js +100 -158
- package/lib/ReactComponentBrowserEnvironment.js +2 -2
- package/lib/ReactComponentEnvironment.js +3 -3
- package/lib/ReactComponentWithPureRenderMixin.js +2 -2
- package/lib/ReactCompositeComponent.js +336 -484
- package/lib/ReactContext.js +14 -4
- package/lib/ReactCurrentOwner.js +2 -2
- package/lib/ReactDOM.js +2 -2
- package/lib/ReactDOMButton.js +2 -2
- package/lib/ReactDOMComponent.js +42 -52
- package/lib/ReactDOMForm.js +2 -2
- package/lib/ReactDOMIDOperations.js +4 -4
- package/lib/ReactDOMIframe.js +43 -0
- package/lib/ReactDOMImg.js +2 -2
- package/lib/ReactDOMInput.js +2 -2
- package/lib/ReactDOMOption.js +2 -2
- package/lib/ReactDOMSelect.js +3 -3
- package/lib/ReactDOMSelection.js +2 -2
- package/lib/ReactDOMTextComponent.js +4 -13
- package/lib/ReactDOMTextarea.js +2 -2
- package/lib/ReactDefaultBatchingStrategy.js +5 -5
- package/lib/ReactDefaultInjection.js +26 -2
- package/lib/ReactDefaultPerf.js +12 -4
- package/lib/ReactDefaultPerfAnalysis.js +1 -1
- package/lib/ReactElement.js +7 -5
- package/lib/ReactElementValidator.js +185 -65
- package/lib/ReactEmptyComponent.js +17 -6
- package/lib/ReactErrorUtils.js +1 -1
- package/lib/ReactEventEmitterMixin.js +2 -2
- package/lib/ReactEventListener.js +4 -5
- package/lib/ReactFragment.js +180 -0
- package/lib/ReactInjection.js +2 -2
- package/lib/ReactInputSelection.js +2 -2
- package/lib/ReactInstanceHandles.js +4 -3
- package/lib/ReactInstanceMap.js +2 -2
- package/lib/ReactLifeCycle.js +35 -0
- package/lib/ReactLink.js +2 -2
- package/lib/ReactMarkupChecksum.js +2 -2
- package/lib/ReactMount.js +87 -23
- package/lib/ReactMultiChild.js +19 -7
- package/lib/ReactMultiChildUpdateTypes.js +2 -2
- package/lib/ReactNativeComponent.js +34 -37
- package/lib/ReactOwner.js +2 -2
- package/lib/ReactPerf.js +2 -2
- package/lib/ReactPropTransferer.js +3 -3
- package/lib/ReactPropTypeLocationNames.js +2 -2
- package/lib/ReactPropTypeLocations.js +2 -2
- package/lib/ReactPropTypes.js +16 -8
- package/lib/ReactPutListenerQueue.js +2 -2
- package/lib/ReactReconcileTransaction.js +2 -2
- package/lib/ReactReconciler.js +121 -0
- package/lib/ReactRef.js +41 -68
- package/lib/ReactRootIndex.js +2 -2
- package/lib/ReactServerRendering.js +4 -3
- package/lib/ReactServerRenderingTransaction.js +2 -2
- package/lib/ReactStateSetters.js +2 -2
- package/lib/ReactTestUtils.js +49 -8
- package/lib/ReactTransitionChildMapping.js +8 -4
- package/lib/ReactTransitionEvents.js +2 -2
- package/lib/ReactTransitionGroup.js +6 -6
- package/lib/ReactUpdateQueue.js +295 -0
- package/lib/ReactUpdates.js +13 -22
- package/lib/ReactWithAddons.js +4 -2
- package/lib/SVGDOMPropertyConfig.js +2 -2
- package/lib/SelectEventPlugin.js +4 -4
- package/lib/ServerReactRootIndex.js +2 -2
- package/lib/SimpleEventPlugin.js +4 -4
- package/lib/SyntheticClipboardEvent.js +2 -3
- package/lib/SyntheticCompositionEvent.js +2 -3
- package/lib/SyntheticDragEvent.js +2 -2
- package/lib/SyntheticEvent.js +12 -4
- package/lib/SyntheticFocusEvent.js +2 -2
- package/lib/SyntheticInputEvent.js +2 -3
- package/lib/SyntheticKeyboardEvent.js +2 -2
- package/lib/SyntheticMouseEvent.js +2 -2
- package/lib/SyntheticTouchEvent.js +2 -2
- package/lib/SyntheticUIEvent.js +2 -2
- package/lib/SyntheticWheelEvent.js +2 -2
- package/lib/Transaction.js +5 -5
- package/lib/ViewportMetrics.js +2 -2
- package/lib/accumulateInto.js +2 -2
- package/lib/adler32.js +2 -2
- 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 +2 -2
- package/lib/createNodesFromMarkup.js +4 -4
- package/lib/cx.js +16 -1
- package/lib/dangerousStyleValue.js +2 -2
- package/lib/emptyFunction.js +1 -1
- package/lib/emptyObject.js +1 -1
- package/lib/{escapeTextForBrowser.js → escapeTextContentForBrowser.js} +10 -11
- package/lib/findDOMNode.js +26 -9
- package/lib/flattenChildren.js +11 -9
- package/lib/focusNode.js +1 -1
- package/lib/forEachAccumulated.js +2 -2
- package/lib/getActiveElement.js +1 -1
- package/lib/getEventCharCode.js +2 -2
- package/lib/getEventKey.js +2 -2
- package/lib/getEventModifierState.js +2 -2
- package/lib/getEventTarget.js +2 -2
- package/lib/getIteratorFn.js +2 -2
- package/lib/getMarkupWrap.js +1 -1
- package/lib/getNodeForCharacterOffset.js +3 -3
- package/lib/getReactRootElementInContainer.js +2 -2
- package/lib/getTextContentAccessor.js +2 -2
- package/lib/getUnboundedScrollPosition.js +1 -1
- package/lib/hyphenate.js +1 -1
- package/lib/hyphenateStyleName.js +1 -1
- package/lib/instantiateReactComponent.js +21 -21
- package/lib/invariant.js +1 -1
- package/lib/isEventSupported.js +2 -2
- package/lib/isNode.js +1 -1
- package/lib/isTextInputElement.js +2 -2
- package/lib/isTextNode.js +1 -1
- package/lib/joinClasses.js +2 -2
- package/lib/keyMirror.js +2 -2
- package/lib/keyOf.js +1 -1
- package/lib/mapObject.js +1 -1
- package/lib/memoizeStringOnly.js +5 -6
- package/lib/onlyChild.js +2 -2
- package/lib/performance.js +1 -1
- package/lib/performanceNow.js +1 -1
- package/lib/quoteAttributeValueForBrowser.js +26 -0
- package/lib/setInnerHTML.js +13 -2
- package/lib/setTextContent.js +40 -0
- package/lib/shallowEqual.js +2 -2
- package/lib/shouldUpdateReactComponent.js +64 -8
- package/lib/toArray.js +2 -2
- package/lib/traverseAllChildren.js +19 -5
- package/lib/update.js +2 -2
- package/lib/warning.js +20 -2
- package/package.json +1 -1
- 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
|
|
@@ -9,181 +9,123 @@
|
|
|
9
9
|
* @providesModule ReactComponent
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
|
-
var
|
|
15
|
-
var ReactRef = require("./ReactRef");
|
|
14
|
+
var ReactUpdateQueue = require("./ReactUpdateQueue");
|
|
16
15
|
|
|
17
16
|
var invariant = require("./invariant");
|
|
17
|
+
var warning = require("./warning");
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function detachRef(ref, component, owner) {
|
|
28
|
-
if (ref instanceof ReactRef) {
|
|
29
|
-
ReactRef.detachRef(ref, component);
|
|
30
|
-
} else {
|
|
31
|
-
ReactOwner.removeComponentAsRefFrom(component, ref, owner);
|
|
32
|
-
}
|
|
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;
|
|
33
25
|
}
|
|
34
26
|
|
|
35
27
|
/**
|
|
36
|
-
*
|
|
28
|
+
* Sets a subset of the state. Always use this to mutate
|
|
29
|
+
* state. You should treat `this.state` as immutable.
|
|
37
30
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* 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.
|
|
41
33
|
*
|
|
42
|
-
*
|
|
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.
|
|
43
38
|
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
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.
|
|
46
45
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
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.
|
|
49
78
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
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.
|
|
52
81
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
* being the child of a component, which means having a DOM representation that
|
|
56
|
-
* is a child of the DOM representation of that component.
|
|
82
|
+
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
83
|
+
* `componentWillUpdate` and `componentDidUpdate`.
|
|
57
84
|
*
|
|
58
|
-
* @
|
|
85
|
+
* @param {?function} callback Called after update is complete.
|
|
86
|
+
* @final
|
|
87
|
+
* @protected
|
|
59
88
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
*
|
|
67
|
-
* @internal
|
|
68
|
-
*/
|
|
69
|
-
BackendIDOperations: null,
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Base functionality for every ReactComponent constructor. Mixed into the
|
|
73
|
-
* `ReactComponent` prototype, but exposed statically for easy access.
|
|
74
|
-
*
|
|
75
|
-
* @lends {ReactComponent.prototype}
|
|
76
|
-
*/
|
|
77
|
-
Mixin: {
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Base constructor for all React components.
|
|
81
|
-
*
|
|
82
|
-
* Subclasses that override this method should make sure to invoke
|
|
83
|
-
* `ReactComponent.Mixin.construct.call(this, ...)`.
|
|
84
|
-
*
|
|
85
|
-
* @param {ReactElement} element
|
|
86
|
-
* @internal
|
|
87
|
-
*/
|
|
88
|
-
construct: function(element) {
|
|
89
|
-
// We keep the old element and a reference to the pending element
|
|
90
|
-
// to track updates.
|
|
91
|
-
this._currentElement = element;
|
|
92
|
-
// These two fields are used by the DOM and ART diffing algorithms
|
|
93
|
-
// respectively. Instead of using expandos on components, we should be
|
|
94
|
-
// storing the state needed by the diffing algorithms elsewhere.
|
|
95
|
-
this._mountIndex = 0;
|
|
96
|
-
this._mountImage = null;
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Initializes the component, renders markup, and registers event listeners.
|
|
101
|
-
*
|
|
102
|
-
* NOTE: This does not insert any nodes into the DOM.
|
|
103
|
-
*
|
|
104
|
-
* Subclasses that override this method should make sure to invoke
|
|
105
|
-
* `ReactComponent.Mixin.mountComponent.call(this, ...)`.
|
|
106
|
-
*
|
|
107
|
-
* @param {string} rootID DOM ID of the root node.
|
|
108
|
-
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
109
|
-
* @return {?string} Rendered markup to be inserted into the DOM.
|
|
110
|
-
* @internal
|
|
111
|
-
*/
|
|
112
|
-
mountComponent: function(rootID, transaction, context) {
|
|
113
|
-
var ref = this._currentElement.ref;
|
|
114
|
-
if (ref != null) {
|
|
115
|
-
var owner = this._currentElement._owner;
|
|
116
|
-
attachRef(ref, this, owner);
|
|
117
|
-
}
|
|
118
|
-
// Effectively: return '';
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Releases any resources allocated by `mountComponent`.
|
|
123
|
-
*
|
|
124
|
-
* NOTE: This does not remove any nodes from the DOM.
|
|
125
|
-
*
|
|
126
|
-
* Subclasses that override this method should make sure to invoke
|
|
127
|
-
* `ReactComponent.Mixin.unmountComponent.call(this)`.
|
|
128
|
-
*
|
|
129
|
-
* @internal
|
|
130
|
-
*/
|
|
131
|
-
unmountComponent: function() {
|
|
132
|
-
var ref = this._currentElement.ref;
|
|
133
|
-
if (ref != null) {
|
|
134
|
-
detachRef(ref, this, this._currentElement._owner);
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Updates the component's currently mounted representation.
|
|
140
|
-
*
|
|
141
|
-
* @param {ReactReconcileTransaction} transaction
|
|
142
|
-
* @param {object} prevElement
|
|
143
|
-
* @param {object} nextElement
|
|
144
|
-
* @internal
|
|
145
|
-
*/
|
|
146
|
-
updateComponent: function(transaction, prevElement, nextElement, context) {
|
|
147
|
-
// If either the owner or a `ref` has changed, make sure the newest owner
|
|
148
|
-
// has stored a reference to `this`, and the previous owner (if different)
|
|
149
|
-
// has forgotten the reference to `this`. We use the element instead
|
|
150
|
-
// of the public this.props because the post processing cannot determine
|
|
151
|
-
// a ref. The ref conceptually lives on the element.
|
|
152
|
-
|
|
153
|
-
// TODO: Should this even be possible? The owner cannot change because
|
|
154
|
-
// it's forbidden by shouldUpdateReactComponent. The ref can change
|
|
155
|
-
// if you swap the keys of but not the refs. Reconsider where this check
|
|
156
|
-
// is made. It probably belongs where the key checking and
|
|
157
|
-
// instantiateReactComponent is done.
|
|
89
|
+
ReactComponent.prototype.forceUpdate = function(callback) {
|
|
90
|
+
ReactUpdateQueue.enqueueForceUpdate(this);
|
|
91
|
+
if (callback) {
|
|
92
|
+
ReactUpdateQueue.enqueueCallback(this, callback);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
158
95
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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;
|
|
167
118
|
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
* @return {?ReactComponent} the actual sibling Component.
|
|
177
|
-
* @internal
|
|
178
|
-
*/
|
|
179
|
-
getPublicInstance: function() {
|
|
180
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
181
|
-
false,
|
|
182
|
-
'getPublicInstance should never be called on the base class. It must ' +
|
|
183
|
-
'be overridden.'
|
|
184
|
-
) : 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]);
|
|
185
127
|
}
|
|
186
128
|
}
|
|
187
|
-
}
|
|
129
|
+
}
|
|
188
130
|
|
|
189
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,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
/*jslint evil: true */
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
'use strict';
|
|
15
15
|
|
|
16
16
|
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
17
17
|
var ReactMount = require("./ReactMount");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2014, Facebook, Inc.
|
|
2
|
+
* Copyright 2014-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
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @providesModule ReactComponentEnvironment
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
14
|
var invariant = require("./invariant");
|
|
15
15
|
|
|
@@ -50,7 +50,7 @@ var ReactComponentEnvironment = {
|
|
|
50
50
|
environment.processChildrenUpdates;
|
|
51
51
|
injected = true;
|
|
52
52
|
}
|
|
53
|
-
}
|
|
53
|
+
}
|
|
54
54
|
|
|
55
55
|
};
|
|
56
56
|
|
|
@@ -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
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @providesModule ReactComponentWithPureRenderMixin
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
14
|
var shallowEqual = require("./shallowEqual");
|
|
15
15
|
|
|
@@ -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
|
|
@@ -9,30 +9,32 @@
|
|
|
9
9
|
* @providesModule ReactCompositeComponent
|
|
10
10
|
*/
|
|
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");
|
|
24
|
+
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
25
|
+
var ReactReconciler = require("./ReactReconciler");
|
|
22
26
|
var ReactUpdates = require("./ReactUpdates");
|
|
23
27
|
|
|
24
28
|
var assign = require("./Object.assign");
|
|
25
29
|
var emptyObject = require("./emptyObject");
|
|
26
30
|
var invariant = require("./invariant");
|
|
27
|
-
var keyMirror = require("./keyMirror");
|
|
28
31
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
29
32
|
var warning = require("./warning");
|
|
30
33
|
|
|
31
34
|
function getDeclarationErrorAddendum(component) {
|
|
32
35
|
var owner = component._currentElement._owner || null;
|
|
33
36
|
if (owner) {
|
|
34
|
-
var
|
|
35
|
-
var name = constructor && (constructor.displayName || constructor.name);
|
|
37
|
+
var name = owner.getName();
|
|
36
38
|
if (name) {
|
|
37
39
|
return ' Check the render method of `' + name + '`.';
|
|
38
40
|
}
|
|
@@ -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
|
-
*
|
|
46
|
+
* ------------------ The Life-Cycle of a Composite Component ------------------
|
|
47
|
+
*
|
|
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
|
|
60
55
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
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
|
|
65
63
|
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
64
|
+
* - componentWillUnmount
|
|
65
|
+
* - [children's componentWillUnmount]
|
|
66
|
+
* - [children destroyed]
|
|
67
|
+
* - (destroyed): The instance is now blank, released by React and ready for GC.
|
|
68
68
|
*
|
|
69
|
-
*
|
|
70
|
-
* | UN | MOUNTED | UN |
|
|
71
|
-
* |MOUNTED| | MOUNTED|
|
|
72
|
-
* +-------+---------------------------------+--------+
|
|
73
|
-
* | ^--------+ +-------+ +--------^ |
|
|
74
|
-
* | | | | | | | |
|
|
75
|
-
* | 0--|MOUNTING|-0-|RECEIVE|-0-| UN |--->0 |
|
|
76
|
-
* | | | |PROPS | |MOUNTING| |
|
|
77
|
-
* | | | | | | | |
|
|
78
|
-
* | | | | | | | |
|
|
79
|
-
* | +--------+ +-------+ +--------+ |
|
|
80
|
-
* | | | |
|
|
81
|
-
* +-------+---------------------------------+--------+
|
|
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,69 +120,108 @@ 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
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
152
|
+
// Since plain JS classes are defined without any special initialization
|
|
153
|
+
// logic, we can not catch common errors early. Therefore, we have to
|
|
154
|
+
// catch them here, at initialization time, instead.
|
|
155
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
156
|
+
!inst.getInitialState ||
|
|
157
|
+
inst.getInitialState.isReactClassApproved,
|
|
158
|
+
'getInitialState was defined on %s, a plain JavaScript class. ' +
|
|
159
|
+
'This is only supported for classes created using React.createClass. ' +
|
|
160
|
+
'Did you mean to define a state property instead?',
|
|
161
|
+
this.getName() || 'a component'
|
|
162
|
+
) : null);
|
|
163
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
164
|
+
!inst.propTypes,
|
|
165
|
+
'propTypes was defined as an instance property on %s. Use a static ' +
|
|
166
|
+
'property to define propTypes instead.',
|
|
167
|
+
this.getName() || 'a component'
|
|
168
|
+
) : null);
|
|
169
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
170
|
+
!inst.contextTypes,
|
|
171
|
+
'contextTypes was defined as an instance property on %s. Use a ' +
|
|
172
|
+
'static property to define contextTypes instead.',
|
|
173
|
+
this.getName() || 'a component'
|
|
174
|
+
) : null);
|
|
175
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
176
|
+
typeof inst.componentShouldUpdate !== 'function',
|
|
177
|
+
'%s has a method called ' +
|
|
178
|
+
'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
|
|
179
|
+
'The name is phrased as a question because the function is ' +
|
|
180
|
+
'expected to return a value.',
|
|
181
|
+
(this.getName() || 'A component')
|
|
182
|
+
) : null);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
var initialState = inst.state;
|
|
186
|
+
if (initialState === undefined) {
|
|
187
|
+
inst.state = initialState = null;
|
|
202
188
|
}
|
|
203
189
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
204
190
|
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
205
|
-
'%s.
|
|
206
|
-
|
|
191
|
+
'%s.state: must be set to an object or null',
|
|
192
|
+
this.getName() || 'ReactCompositeComponent'
|
|
207
193
|
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
208
|
-
inst.state = initialState;
|
|
209
194
|
|
|
210
|
-
this.
|
|
195
|
+
this._pendingStateQueue = null;
|
|
196
|
+
this._pendingReplaceState = false;
|
|
211
197
|
this._pendingForceUpdate = false;
|
|
212
198
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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
|
+
}
|
|
220
211
|
}
|
|
212
|
+
|
|
213
|
+
renderedElement = this._renderValidatedComponent();
|
|
214
|
+
} finally {
|
|
215
|
+
ReactLifeCycle.currentlyMountingInstance = previouslyMounting;
|
|
221
216
|
}
|
|
222
217
|
|
|
223
|
-
var renderedElement = this._renderValidatedComponent();
|
|
224
218
|
this._renderedComponent = this._instantiateReactComponent(
|
|
225
219
|
renderedElement,
|
|
226
220
|
this._currentElement.type // The wrapping type
|
|
227
221
|
);
|
|
228
222
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
var markup = this._renderedComponent.mountComponent(
|
|
223
|
+
var markup = ReactReconciler.mountComponent(
|
|
224
|
+
this._renderedComponent,
|
|
232
225
|
rootID,
|
|
233
226
|
transaction,
|
|
234
227
|
this._processChildContext(context)
|
|
@@ -236,6 +229,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
236
229
|
if (inst.componentDidMount) {
|
|
237
230
|
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
|
238
231
|
}
|
|
232
|
+
|
|
239
233
|
return markup;
|
|
240
234
|
},
|
|
241
235
|
|
|
@@ -248,25 +242,28 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
248
242
|
unmountComponent: function() {
|
|
249
243
|
var inst = this._instance;
|
|
250
244
|
|
|
251
|
-
this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
|
|
252
245
|
if (inst.componentWillUnmount) {
|
|
253
|
-
|
|
246
|
+
var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance;
|
|
247
|
+
ReactLifeCycle.currentlyUnmountingInstance = this;
|
|
248
|
+
try {
|
|
249
|
+
inst.componentWillUnmount();
|
|
250
|
+
} finally {
|
|
251
|
+
ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting;
|
|
252
|
+
}
|
|
254
253
|
}
|
|
255
|
-
this._compositeLifeCycleState = null;
|
|
256
254
|
|
|
257
|
-
this._renderedComponent
|
|
255
|
+
ReactReconciler.unmountComponent(this._renderedComponent);
|
|
258
256
|
this._renderedComponent = null;
|
|
259
257
|
|
|
260
258
|
// Reset pending fields
|
|
261
|
-
this.
|
|
259
|
+
this._pendingStateQueue = null;
|
|
260
|
+
this._pendingReplaceState = false;
|
|
262
261
|
this._pendingForceUpdate = false;
|
|
263
262
|
this._pendingCallbacks = null;
|
|
264
263
|
this._pendingElement = null;
|
|
265
264
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
ReactComponentEnvironment.unmountIDFromEnvironment(this._rootNodeID);
|
|
269
|
-
|
|
265
|
+
// These fields do not really need to be reset since this object is no
|
|
266
|
+
// longer accessible.
|
|
270
267
|
this._context = null;
|
|
271
268
|
this._rootNodeID = null;
|
|
272
269
|
|
|
@@ -282,50 +279,6 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
282
279
|
// TODO: inst.context = null;
|
|
283
280
|
},
|
|
284
281
|
|
|
285
|
-
/**
|
|
286
|
-
* Sets a subset of the props.
|
|
287
|
-
*
|
|
288
|
-
* @param {object} partialProps Subset of the next props.
|
|
289
|
-
* @param {?function} callback Called after props are updated.
|
|
290
|
-
* @final
|
|
291
|
-
* @public
|
|
292
|
-
*/
|
|
293
|
-
setProps: function(partialProps, callback) {
|
|
294
|
-
// Merge with the pending element if it exists, otherwise with existing
|
|
295
|
-
// element props.
|
|
296
|
-
var element = this._pendingElement || this._currentElement;
|
|
297
|
-
this.replaceProps(
|
|
298
|
-
assign({}, element.props, partialProps),
|
|
299
|
-
callback
|
|
300
|
-
);
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* Replaces all of the props.
|
|
305
|
-
*
|
|
306
|
-
* @param {object} props New props.
|
|
307
|
-
* @param {?function} callback Called after props are updated.
|
|
308
|
-
* @final
|
|
309
|
-
* @public
|
|
310
|
-
*/
|
|
311
|
-
replaceProps: function(props, callback) {
|
|
312
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
313
|
-
this._isTopLevel,
|
|
314
|
-
'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
|
|
315
|
-
'component with a parent. This is an anti-pattern since props will ' +
|
|
316
|
-
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
317
|
-
'`render` method to pass the correct value as props to the component ' +
|
|
318
|
-
'where it is created.'
|
|
319
|
-
) : invariant(this._isTopLevel));
|
|
320
|
-
// This is a deoptimized path. We optimize for always having an element.
|
|
321
|
-
// This creates an extra internal element.
|
|
322
|
-
this._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
323
|
-
this._pendingElement || this._currentElement,
|
|
324
|
-
props
|
|
325
|
-
);
|
|
326
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
327
|
-
},
|
|
328
|
-
|
|
329
282
|
/**
|
|
330
283
|
* Schedule a partial update to the props. Only used for internal testing.
|
|
331
284
|
*
|
|
@@ -345,89 +298,22 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
345
298
|
ReactUpdates.enqueueUpdate(this, callback);
|
|
346
299
|
},
|
|
347
300
|
|
|
348
|
-
/**
|
|
349
|
-
* Sets a subset of the state. This only exists because _pendingState is
|
|
350
|
-
* internal. This provides a merging strategy that is not available to deep
|
|
351
|
-
* properties which is confusing. TODO: Expose pendingState or don't use it
|
|
352
|
-
* during the merge.
|
|
353
|
-
*
|
|
354
|
-
* @param {object} partialState Next partial state to be merged with state.
|
|
355
|
-
* @param {?function} callback Called after state is updated.
|
|
356
|
-
* @final
|
|
357
|
-
* @protected
|
|
358
|
-
*/
|
|
359
|
-
setState: function(partialState, callback) {
|
|
360
|
-
// Merge with `_pendingState` if it exists, otherwise with existing state.
|
|
361
|
-
this.replaceState(
|
|
362
|
-
assign({}, this._pendingState || this._instance.state, partialState),
|
|
363
|
-
callback
|
|
364
|
-
);
|
|
365
|
-
},
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Replaces all of the state. Always use this or `setState` to mutate state.
|
|
369
|
-
* You should treat `this.state` as immutable.
|
|
370
|
-
*
|
|
371
|
-
* There is no guarantee that `this.state` will be immediately updated, so
|
|
372
|
-
* accessing `this.state` after calling this method may return the old value.
|
|
373
|
-
*
|
|
374
|
-
* @param {object} completeState Next state.
|
|
375
|
-
* @param {?function} callback Called after state is updated.
|
|
376
|
-
* @final
|
|
377
|
-
* @protected
|
|
378
|
-
*/
|
|
379
|
-
replaceState: function(completeState, callback) {
|
|
380
|
-
validateLifeCycleOnReplaceState(this);
|
|
381
|
-
this._pendingState = completeState;
|
|
382
|
-
if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) {
|
|
383
|
-
// If we're in a componentWillMount handler, don't enqueue a rerender
|
|
384
|
-
// because ReactUpdates assumes we're in a browser context (which is wrong
|
|
385
|
-
// for server rendering) and we're about to do a render anyway.
|
|
386
|
-
// TODO: The callback here is ignored when setState is called from
|
|
387
|
-
// componentWillMount. Either fix it or disallow doing so completely in
|
|
388
|
-
// favor of getInitialState.
|
|
389
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
390
|
-
}
|
|
391
|
-
},
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Forces an update. This should only be invoked when it is known with
|
|
395
|
-
* certainty that we are **not** in a DOM transaction.
|
|
396
|
-
*
|
|
397
|
-
* You may want to call this when you know that some deeper aspect of the
|
|
398
|
-
* component's state has changed but `setState` was not called.
|
|
399
|
-
*
|
|
400
|
-
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
401
|
-
* `componentWillUpdate` and `componentDidUpdate`.
|
|
402
|
-
*
|
|
403
|
-
* @param {?function} callback Called after update is complete.isM
|
|
404
|
-
* @final
|
|
405
|
-
* @protected
|
|
406
|
-
*/
|
|
407
|
-
forceUpdate: function(callback) {
|
|
408
|
-
var compositeLifeCycleState = this._compositeLifeCycleState;
|
|
409
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
410
|
-
compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
|
|
411
|
-
compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
|
|
412
|
-
'forceUpdate(...): Cannot force an update while unmounting component ' +
|
|
413
|
-
'or during an existing state transition (such as within `render`).'
|
|
414
|
-
) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
|
|
415
|
-
compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
|
|
416
|
-
this._pendingForceUpdate = true;
|
|
417
|
-
ReactUpdates.enqueueUpdate(this, callback);
|
|
418
|
-
},
|
|
419
|
-
|
|
420
301
|
/**
|
|
421
302
|
* Filters the context object to only contain keys specified in
|
|
422
|
-
* `contextTypes
|
|
303
|
+
* `contextTypes`
|
|
423
304
|
*
|
|
424
305
|
* @param {object} context
|
|
425
306
|
* @return {?object}
|
|
426
307
|
* @private
|
|
427
308
|
*/
|
|
428
|
-
|
|
309
|
+
_maskContext: function(context) {
|
|
429
310
|
var maskedContext = null;
|
|
430
|
-
|
|
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;
|
|
431
317
|
if (!contextTypes) {
|
|
432
318
|
return emptyObject;
|
|
433
319
|
}
|
|
@@ -435,12 +321,30 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
435
321
|
for (var contextName in contextTypes) {
|
|
436
322
|
maskedContext[contextName] = context[contextName];
|
|
437
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);
|
|
438
337
|
if ("production" !== process.env.NODE_ENV) {
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
maskedContext,
|
|
442
|
-
ReactPropTypeLocations.context
|
|
338
|
+
var Component = ReactNativeComponent.getComponentClassForElement(
|
|
339
|
+
this._currentElement
|
|
443
340
|
);
|
|
341
|
+
if (Component.contextTypes) {
|
|
342
|
+
this._checkPropTypes(
|
|
343
|
+
Component.contextTypes,
|
|
344
|
+
maskedContext,
|
|
345
|
+
ReactPropTypeLocations.context
|
|
346
|
+
);
|
|
347
|
+
}
|
|
444
348
|
}
|
|
445
349
|
return maskedContext;
|
|
446
350
|
},
|
|
@@ -453,13 +357,12 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
453
357
|
_processChildContext: function(currentContext) {
|
|
454
358
|
var inst = this._instance;
|
|
455
359
|
var childContext = inst.getChildContext && inst.getChildContext();
|
|
456
|
-
var displayName = inst.constructor.displayName || 'ReactCompositeComponent';
|
|
457
360
|
if (childContext) {
|
|
458
361
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
459
362
|
typeof inst.constructor.childContextTypes === 'object',
|
|
460
363
|
'%s.getChildContext(): childContextTypes must be defined in order to ' +
|
|
461
364
|
'use getChildContext().',
|
|
462
|
-
|
|
365
|
+
this.getName() || 'ReactCompositeComponent'
|
|
463
366
|
) : invariant(typeof inst.constructor.childContextTypes === 'object'));
|
|
464
367
|
if ("production" !== process.env.NODE_ENV) {
|
|
465
368
|
this._checkPropTypes(
|
|
@@ -472,7 +375,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
472
375
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
473
376
|
name in inst.constructor.childContextTypes,
|
|
474
377
|
'%s.getChildContext(): key "%s" is not defined in childContextTypes.',
|
|
475
|
-
|
|
378
|
+
this.getName() || 'ReactCompositeComponent',
|
|
476
379
|
name
|
|
477
380
|
) : invariant(name in inst.constructor.childContextTypes));
|
|
478
381
|
}
|
|
@@ -492,10 +395,15 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
492
395
|
*/
|
|
493
396
|
_processProps: function(newProps) {
|
|
494
397
|
if ("production" !== process.env.NODE_ENV) {
|
|
495
|
-
var
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
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
|
+
);
|
|
499
407
|
}
|
|
500
408
|
}
|
|
501
409
|
return newProps;
|
|
@@ -512,85 +420,97 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
512
420
|
_checkPropTypes: function(propTypes, props, location) {
|
|
513
421
|
// TODO: Stop validating prop types here and only use the element
|
|
514
422
|
// validation.
|
|
515
|
-
var componentName = this.
|
|
516
|
-
this._instance.constructor.name;
|
|
423
|
+
var componentName = this.getName();
|
|
517
424
|
for (var propName in propTypes) {
|
|
518
425
|
if (propTypes.hasOwnProperty(propName)) {
|
|
519
|
-
var error
|
|
520
|
-
|
|
426
|
+
var error;
|
|
427
|
+
try {
|
|
428
|
+
// This is intentionally an invariant that gets caught. It's the same
|
|
429
|
+
// behavior as without this statement except with a better message.
|
|
430
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
431
|
+
typeof propTypes[propName] === 'function',
|
|
432
|
+
'%s: %s type `%s` is invalid; it must be a function, usually ' +
|
|
433
|
+
'from React.PropTypes.',
|
|
434
|
+
componentName || 'React class',
|
|
435
|
+
ReactPropTypeLocationNames[location],
|
|
436
|
+
propName
|
|
437
|
+
) : invariant(typeof propTypes[propName] === 'function'));
|
|
438
|
+
error = propTypes[propName](props, propName, componentName, location);
|
|
439
|
+
} catch (ex) {
|
|
440
|
+
error = ex;
|
|
441
|
+
}
|
|
521
442
|
if (error instanceof Error) {
|
|
522
443
|
// We may want to extend this logic for similar errors in
|
|
523
444
|
// React.render calls, so I'm abstracting it away into
|
|
524
445
|
// a function to minimize refactoring in the future
|
|
525
446
|
var addendum = getDeclarationErrorAddendum(this);
|
|
526
|
-
|
|
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',
|
|
453
|
+
error.message + addendum
|
|
454
|
+
) : null);
|
|
455
|
+
} else {
|
|
456
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
457
|
+
false,
|
|
458
|
+
'Failed Context Types: %s',
|
|
459
|
+
error.message + addendum
|
|
460
|
+
) : null);
|
|
461
|
+
}
|
|
527
462
|
}
|
|
528
463
|
}
|
|
529
464
|
}
|
|
530
465
|
},
|
|
531
466
|
|
|
532
|
-
receiveComponent: function(nextElement, transaction,
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
// superfluous reconcile. It's possible for state to be mutable but such
|
|
538
|
-
// change should trigger an update of the owner which would recreate
|
|
539
|
-
// the element. We explicitly check for the existence of an owner since
|
|
540
|
-
// it's possible for an element created outside a composite to be
|
|
541
|
-
// deeply mutated and reused.
|
|
542
|
-
return;
|
|
543
|
-
}
|
|
467
|
+
receiveComponent: function(nextElement, transaction, nextContext) {
|
|
468
|
+
var prevElement = this._currentElement;
|
|
469
|
+
var prevContext = this._context;
|
|
470
|
+
|
|
471
|
+
this._pendingElement = null;
|
|
544
472
|
|
|
545
|
-
this.
|
|
546
|
-
|
|
547
|
-
|
|
473
|
+
this.updateComponent(
|
|
474
|
+
transaction,
|
|
475
|
+
prevElement,
|
|
476
|
+
nextElement,
|
|
477
|
+
prevContext,
|
|
478
|
+
nextContext
|
|
479
|
+
);
|
|
548
480
|
},
|
|
549
481
|
|
|
550
482
|
/**
|
|
551
|
-
* If any of `_pendingElement`, `
|
|
483
|
+
* If any of `_pendingElement`, `_pendingStateQueue`, or `_pendingForceUpdate`
|
|
552
484
|
* is set, update the component.
|
|
553
485
|
*
|
|
554
486
|
* @param {ReactReconcileTransaction} transaction
|
|
555
487
|
* @internal
|
|
556
488
|
*/
|
|
557
489
|
performUpdateIfNecessary: function(transaction) {
|
|
558
|
-
var compositeLifeCycleState = this._compositeLifeCycleState;
|
|
559
|
-
// Do not trigger a state transition if we are in the middle of mounting or
|
|
560
|
-
// receiving props because both of those will already be doing this.
|
|
561
|
-
if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
|
|
562
|
-
compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (this._pendingElement == null &&
|
|
567
|
-
this._pendingState == null &&
|
|
568
|
-
this._pendingContext == null &&
|
|
569
|
-
!this._pendingForceUpdate) {
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
var prevElement = this._currentElement;
|
|
574
|
-
var nextElement = prevElement;
|
|
575
490
|
if (this._pendingElement != null) {
|
|
576
|
-
|
|
577
|
-
|
|
491
|
+
ReactReconciler.receiveComponent(
|
|
492
|
+
this,
|
|
493
|
+
this._pendingElement || this._currentElement,
|
|
494
|
+
transaction,
|
|
495
|
+
this._context
|
|
496
|
+
);
|
|
578
497
|
}
|
|
579
498
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
499
|
+
if (this._pendingStateQueue !== null || this._pendingForceUpdate) {
|
|
500
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
501
|
+
ReactElementValidator.checkAndWarnForMutatedProps(
|
|
502
|
+
this._currentElement
|
|
503
|
+
);
|
|
504
|
+
}
|
|
586
505
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
506
|
+
this.updateComponent(
|
|
507
|
+
transaction,
|
|
508
|
+
this._currentElement,
|
|
509
|
+
this._currentElement,
|
|
510
|
+
this._context,
|
|
511
|
+
this._context
|
|
512
|
+
);
|
|
513
|
+
}
|
|
594
514
|
},
|
|
595
515
|
|
|
596
516
|
/**
|
|
@@ -598,35 +518,22 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
598
518
|
* TODO: Remove this check when owner-context is removed
|
|
599
519
|
*/
|
|
600
520
|
_warnIfContextsDiffer: function(ownerBasedContext, parentBasedContext) {
|
|
601
|
-
|
|
521
|
+
ownerBasedContext = this._maskContext(ownerBasedContext);
|
|
522
|
+
parentBasedContext = this._maskContext(parentBasedContext);
|
|
602
523
|
var parentKeys = Object.keys(parentBasedContext).sort();
|
|
603
|
-
var displayName = this.
|
|
604
|
-
|
|
605
|
-
|
|
524
|
+
var displayName = this.getName() || 'ReactCompositeComponent';
|
|
525
|
+
for (var i = 0; i < parentKeys.length; i++) {
|
|
526
|
+
var key = parentKeys[i];
|
|
606
527
|
("production" !== process.env.NODE_ENV ? warning(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
'
|
|
610
|
-
'context (keys: %s) while mounting %s ' +
|
|
528
|
+
ownerBasedContext[key] === parentBasedContext[key],
|
|
529
|
+
'owner-based and parent-based contexts differ ' +
|
|
530
|
+
'(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
|
|
611
531
|
'(see: http://fb.me/react-context-by-parent)',
|
|
612
|
-
|
|
613
|
-
|
|
532
|
+
ownerBasedContext[key],
|
|
533
|
+
parentBasedContext[key],
|
|
534
|
+
key,
|
|
614
535
|
displayName
|
|
615
536
|
) : null);
|
|
616
|
-
} else {
|
|
617
|
-
for (var i = 0; i < parentKeys.length; i++) {
|
|
618
|
-
var key = parentKeys[i];
|
|
619
|
-
("production" !== process.env.NODE_ENV ? warning(
|
|
620
|
-
ownerBasedContext[key] === parentBasedContext[key],
|
|
621
|
-
'owner-based and parent-based contexts differ ' +
|
|
622
|
-
'(values: `%s` vs `%s`) for key (%s) while mounting %s ' +
|
|
623
|
-
'(see: http://fb.me/react-context-by-parent)',
|
|
624
|
-
ownerBasedContext[key],
|
|
625
|
-
parentBasedContext[key],
|
|
626
|
-
key,
|
|
627
|
-
displayName
|
|
628
|
-
) : null);
|
|
629
|
-
}
|
|
630
537
|
}
|
|
631
538
|
},
|
|
632
539
|
|
|
@@ -652,37 +559,35 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
652
559
|
prevUnmaskedContext,
|
|
653
560
|
nextUnmaskedContext
|
|
654
561
|
) {
|
|
655
|
-
// Update refs regardless of what shouldComponentUpdate returns
|
|
656
|
-
ReactComponent.Mixin.updateComponent.call(
|
|
657
|
-
this,
|
|
658
|
-
transaction,
|
|
659
|
-
prevParentElement,
|
|
660
|
-
nextParentElement,
|
|
661
|
-
prevUnmaskedContext,
|
|
662
|
-
nextUnmaskedContext
|
|
663
|
-
);
|
|
664
|
-
|
|
665
562
|
var inst = this._instance;
|
|
666
563
|
|
|
667
|
-
var
|
|
668
|
-
var
|
|
669
|
-
|
|
670
|
-
var nextProps = prevProps;
|
|
564
|
+
var nextContext = inst.context;
|
|
565
|
+
var nextProps = inst.props;
|
|
566
|
+
|
|
671
567
|
// Distinguish between a props update versus a simple state update
|
|
672
568
|
if (prevParentElement !== nextParentElement) {
|
|
673
569
|
nextContext = this._processContext(nextParentElement._context);
|
|
674
570
|
nextProps = this._processProps(nextParentElement.props);
|
|
675
571
|
|
|
676
|
-
|
|
572
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
573
|
+
if (nextUnmaskedContext != null) {
|
|
574
|
+
this._warnIfContextsDiffer(
|
|
575
|
+
nextParentElement._context,
|
|
576
|
+
nextUnmaskedContext
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
// An update here will schedule an update but immediately set
|
|
582
|
+
// _pendingStateQueue which will ensure that any state updates gets
|
|
583
|
+
// immediately reconciled instead of waiting for the next batch.
|
|
584
|
+
|
|
677
585
|
if (inst.componentWillReceiveProps) {
|
|
678
586
|
inst.componentWillReceiveProps(nextProps, nextContext);
|
|
679
587
|
}
|
|
680
588
|
}
|
|
681
589
|
|
|
682
|
-
this.
|
|
683
|
-
|
|
684
|
-
var nextState = this._pendingState || inst.state;
|
|
685
|
-
this._pendingState = null;
|
|
590
|
+
var nextState = this._processPendingState(nextProps, nextContext);
|
|
686
591
|
|
|
687
592
|
var shouldUpdate =
|
|
688
593
|
this._pendingForceUpdate ||
|
|
@@ -690,16 +595,26 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
690
595
|
inst.shouldComponentUpdate(nextProps, nextState, nextContext);
|
|
691
596
|
|
|
692
597
|
if ("production" !== process.env.NODE_ENV) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
598
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
599
|
+
typeof shouldUpdate !== 'undefined',
|
|
600
|
+
'%s.shouldComponentUpdate(): Returned undefined instead of a ' +
|
|
601
|
+
'boolean value. Make sure to return true or false.',
|
|
602
|
+
this.getName() || 'ReactCompositeComponent'
|
|
603
|
+
) : null);
|
|
700
604
|
}
|
|
701
605
|
|
|
702
|
-
if (
|
|
606
|
+
if (shouldUpdate) {
|
|
607
|
+
this._pendingForceUpdate = false;
|
|
608
|
+
// Will set `this.props`, `this.state` and `this.context`.
|
|
609
|
+
this._performComponentUpdate(
|
|
610
|
+
nextParentElement,
|
|
611
|
+
nextProps,
|
|
612
|
+
nextState,
|
|
613
|
+
nextContext,
|
|
614
|
+
transaction,
|
|
615
|
+
nextUnmaskedContext
|
|
616
|
+
);
|
|
617
|
+
} else {
|
|
703
618
|
// If it's determined that a component should not update, we still want
|
|
704
619
|
// to set props and state but we shortcut the rest of the update.
|
|
705
620
|
this._currentElement = nextParentElement;
|
|
@@ -707,19 +622,32 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
707
622
|
inst.props = nextProps;
|
|
708
623
|
inst.state = nextState;
|
|
709
624
|
inst.context = nextContext;
|
|
710
|
-
return;
|
|
711
625
|
}
|
|
626
|
+
},
|
|
712
627
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
this.
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
628
|
+
_processPendingState: function(props, context) {
|
|
629
|
+
var inst = this._instance;
|
|
630
|
+
var queue = this._pendingStateQueue;
|
|
631
|
+
var replace = this._pendingReplaceState;
|
|
632
|
+
this._pendingReplaceState = false;
|
|
633
|
+
this._pendingStateQueue = null;
|
|
634
|
+
|
|
635
|
+
if (!queue) {
|
|
636
|
+
return inst.state;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
var nextState = assign({}, replace ? queue[0] : inst.state);
|
|
640
|
+
for (var i = replace ? 1 : 0; i < queue.length; i++) {
|
|
641
|
+
var partial = queue[i];
|
|
642
|
+
assign(
|
|
643
|
+
nextState,
|
|
644
|
+
typeof partial === 'function' ?
|
|
645
|
+
partial.call(inst, nextState, props, context) :
|
|
646
|
+
partial
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
return nextState;
|
|
723
651
|
},
|
|
724
652
|
|
|
725
653
|
/**
|
|
@@ -758,7 +686,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
758
686
|
inst.state = nextState;
|
|
759
687
|
inst.context = nextContext;
|
|
760
688
|
|
|
761
|
-
this._updateRenderedComponent(transaction,
|
|
689
|
+
this._updateRenderedComponent(transaction, unmaskedContext);
|
|
762
690
|
|
|
763
691
|
if (inst.componentDidUpdate) {
|
|
764
692
|
transaction.getReactMountReady().enqueue(
|
|
@@ -779,7 +707,8 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
779
707
|
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
780
708
|
var nextRenderedElement = this._renderValidatedComponent();
|
|
781
709
|
if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) {
|
|
782
|
-
|
|
710
|
+
ReactReconciler.receiveComponent(
|
|
711
|
+
prevComponentInstance,
|
|
783
712
|
nextRenderedElement,
|
|
784
713
|
transaction,
|
|
785
714
|
this._processChildContext(context)
|
|
@@ -788,26 +717,34 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
788
717
|
// These two IDs are actually the same! But nothing should rely on that.
|
|
789
718
|
var thisID = this._rootNodeID;
|
|
790
719
|
var prevComponentID = prevComponentInstance._rootNodeID;
|
|
791
|
-
|
|
720
|
+
ReactReconciler.unmountComponent(prevComponentInstance);
|
|
792
721
|
|
|
793
722
|
this._renderedComponent = this._instantiateReactComponent(
|
|
794
723
|
nextRenderedElement,
|
|
795
724
|
this._currentElement.type
|
|
796
725
|
);
|
|
797
|
-
var nextMarkup =
|
|
726
|
+
var nextMarkup = ReactReconciler.mountComponent(
|
|
727
|
+
this._renderedComponent,
|
|
798
728
|
thisID,
|
|
799
729
|
transaction,
|
|
800
730
|
context
|
|
801
731
|
);
|
|
802
|
-
|
|
803
|
-
prevComponentID,
|
|
804
|
-
nextMarkup
|
|
805
|
-
);
|
|
732
|
+
this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup);
|
|
806
733
|
}
|
|
807
734
|
},
|
|
808
735
|
|
|
809
736
|
/**
|
|
810
|
-
* @
|
|
737
|
+
* @protected
|
|
738
|
+
*/
|
|
739
|
+
_replaceNodeWithMarkupByID: function(prevComponentID, nextMarkup) {
|
|
740
|
+
ReactComponentEnvironment.replaceNodeWithMarkupByID(
|
|
741
|
+
prevComponentID,
|
|
742
|
+
nextMarkup
|
|
743
|
+
);
|
|
744
|
+
},
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* @protected
|
|
811
748
|
*/
|
|
812
749
|
_renderValidatedComponentWithoutOwnerOrContext: function() {
|
|
813
750
|
var inst = this._instance;
|
|
@@ -835,7 +772,6 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
835
772
|
this._currentElement._context
|
|
836
773
|
);
|
|
837
774
|
ReactCurrentOwner.current = this;
|
|
838
|
-
var inst = this._instance;
|
|
839
775
|
try {
|
|
840
776
|
renderedComponent =
|
|
841
777
|
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
@@ -849,7 +785,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
849
785
|
ReactElement.isValidElement(renderedComponent),
|
|
850
786
|
'%s.render(): A valid ReactComponent must be returned. You may have ' +
|
|
851
787
|
'returned undefined, an array or some other invalid object.',
|
|
852
|
-
|
|
788
|
+
this.getName() || 'ReactCompositeComponent'
|
|
853
789
|
) : invariant(// TODO: An `isValidNode` function would probably be more appropriate
|
|
854
790
|
renderedComponent === null || renderedComponent === false ||
|
|
855
791
|
ReactElement.isValidElement(renderedComponent)));
|
|
@@ -882,6 +818,22 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
882
818
|
delete refs[ref];
|
|
883
819
|
},
|
|
884
820
|
|
|
821
|
+
/**
|
|
822
|
+
* Get a text description of the component that can be used to identify it
|
|
823
|
+
* in error messages.
|
|
824
|
+
* @return {string} The name or null.
|
|
825
|
+
* @internal
|
|
826
|
+
*/
|
|
827
|
+
getName: function() {
|
|
828
|
+
var type = this._currentElement.type;
|
|
829
|
+
var constructor = this._instance && this._instance.constructor;
|
|
830
|
+
return (
|
|
831
|
+
type.displayName || (constructor && constructor.displayName) ||
|
|
832
|
+
type.name || (constructor && constructor.name) ||
|
|
833
|
+
null
|
|
834
|
+
);
|
|
835
|
+
},
|
|
836
|
+
|
|
885
837
|
/**
|
|
886
838
|
* Get the publicly accessible representation of this component - i.e. what
|
|
887
839
|
* is exposed by refs and returned by React.render. Can be null for stateless
|
|
@@ -897,103 +849,7 @@ var ReactCompositeComponentMixin = assign({},
|
|
|
897
849
|
// Stub
|
|
898
850
|
_instantiateReactComponent: null
|
|
899
851
|
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
var ShallowMixin = assign({},
|
|
903
|
-
ReactCompositeComponentMixin, {
|
|
904
|
-
|
|
905
|
-
/**
|
|
906
|
-
* Initializes the component, renders markup, and registers event listeners.
|
|
907
|
-
*
|
|
908
|
-
* @param {string} rootID DOM ID of the root node.
|
|
909
|
-
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
910
|
-
* @return {ReactElement} Shallow rendering of the component.
|
|
911
|
-
* @final
|
|
912
|
-
* @internal
|
|
913
|
-
*/
|
|
914
|
-
mountComponent: function(rootID, transaction, context) {
|
|
915
|
-
ReactComponent.Mixin.mountComponent.call(
|
|
916
|
-
this,
|
|
917
|
-
rootID,
|
|
918
|
-
transaction,
|
|
919
|
-
context
|
|
920
|
-
);
|
|
921
|
-
|
|
922
|
-
var inst = this._instance;
|
|
923
|
-
|
|
924
|
-
// Store a reference from the instance back to the internal representation
|
|
925
|
-
ReactInstanceMap.set(inst, this);
|
|
926
|
-
|
|
927
|
-
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
|
928
|
-
|
|
929
|
-
// No context for shallow-mounted components.
|
|
930
|
-
inst.props = this._processProps(this._currentElement.props);
|
|
931
|
-
|
|
932
|
-
var initialState = inst.getInitialState ? inst.getInitialState() : null;
|
|
933
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
934
|
-
// We allow auto-mocks to proceed as if they're returning null.
|
|
935
|
-
if (typeof initialState === 'undefined' &&
|
|
936
|
-
inst.getInitialState._isMockFunction) {
|
|
937
|
-
// This is probably bad practice. Consider warning here and
|
|
938
|
-
// deprecating this convenience.
|
|
939
|
-
initialState = null;
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
943
|
-
typeof initialState === 'object' && !Array.isArray(initialState),
|
|
944
|
-
'%s.getInitialState(): must return an object or null',
|
|
945
|
-
inst.constructor.displayName || 'ReactCompositeComponent'
|
|
946
|
-
) : invariant(typeof initialState === 'object' && !Array.isArray(initialState)));
|
|
947
|
-
inst.state = initialState;
|
|
948
|
-
|
|
949
|
-
this._pendingState = null;
|
|
950
|
-
this._pendingForceUpdate = false;
|
|
951
|
-
|
|
952
|
-
if (inst.componentWillMount) {
|
|
953
|
-
inst.componentWillMount();
|
|
954
|
-
// When mounting, calls to `setState` by `componentWillMount` will set
|
|
955
|
-
// `this._pendingState` without triggering a re-render.
|
|
956
|
-
if (this._pendingState) {
|
|
957
|
-
inst.state = this._pendingState;
|
|
958
|
-
this._pendingState = null;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
// No recursive call to instantiateReactComponent for shallow rendering.
|
|
963
|
-
this._renderedComponent =
|
|
964
|
-
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
965
|
-
|
|
966
|
-
// Done with mounting, `setState` will now trigger UI changes.
|
|
967
|
-
this._compositeLifeCycleState = null;
|
|
968
|
-
|
|
969
|
-
// No call to this._renderedComponent.mountComponent for shallow
|
|
970
|
-
// rendering.
|
|
971
|
-
|
|
972
|
-
if (inst.componentDidMount) {
|
|
973
|
-
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
return this._renderedComponent;
|
|
977
|
-
},
|
|
978
|
-
|
|
979
|
-
/**
|
|
980
|
-
* Call the component's `render` method and update the DOM accordingly.
|
|
981
|
-
*
|
|
982
|
-
* @param {ReactReconcileTransaction} transaction
|
|
983
|
-
* @internal
|
|
984
|
-
*/
|
|
985
|
-
_updateRenderedComponent: function(transaction) {
|
|
986
|
-
var prevComponentInstance = this._renderedComponent;
|
|
987
|
-
var prevRenderedElement = prevComponentInstance._currentElement;
|
|
988
|
-
// Use the without-owner-or-context variant of _rVC below:
|
|
989
|
-
var nextRenderedElement =
|
|
990
|
-
this._renderValidatedComponentWithoutOwnerOrContext();
|
|
991
|
-
// This is a noop in shallow render
|
|
992
|
-
shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement);
|
|
993
|
-
this._renderedComponent = nextRenderedElement;
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
});
|
|
852
|
+
};
|
|
997
853
|
|
|
998
854
|
ReactPerf.measureMethods(
|
|
999
855
|
ReactCompositeComponentMixin,
|
|
@@ -1007,11 +863,7 @@ ReactPerf.measureMethods(
|
|
|
1007
863
|
|
|
1008
864
|
var ReactCompositeComponent = {
|
|
1009
865
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
Mixin: ReactCompositeComponentMixin,
|
|
1013
|
-
|
|
1014
|
-
ShallowMixin: ShallowMixin
|
|
866
|
+
Mixin: ReactCompositeComponentMixin
|
|
1015
867
|
|
|
1016
868
|
};
|
|
1017
869
|
|