mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #2465 from yungsters/perf
Preserve Implicit Method Names
This commit is contained in:
@@ -171,28 +171,24 @@ ReactDOMComponent.Mixin = {
|
||||
* @param {number} mountDepth number of components in the owner hierarchy
|
||||
* @return {string} The computed markup.
|
||||
*/
|
||||
mountComponent: ReactPerf.measure(
|
||||
'ReactDOMComponent',
|
||||
'mountComponent',
|
||||
function(rootID, transaction, mountDepth, context) {
|
||||
invariant(context !== undefined, "Context is required parameter");
|
||||
ReactComponent.Mixin.mountComponent.call(
|
||||
this,
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth,
|
||||
context
|
||||
);
|
||||
this._rootNodeID = rootID;
|
||||
assertValidProps(this._currentElement.props);
|
||||
var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
|
||||
return (
|
||||
this._createOpenTagMarkupAndPutListeners(transaction) +
|
||||
this._createContentMarkup(transaction, context) +
|
||||
closeTag
|
||||
);
|
||||
}
|
||||
),
|
||||
mountComponent: function(rootID, transaction, mountDepth, context) {
|
||||
invariant(context !== undefined, "Context is required parameter");
|
||||
ReactComponent.Mixin.mountComponent.call(
|
||||
this,
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth,
|
||||
context
|
||||
);
|
||||
this._rootNodeID = rootID;
|
||||
assertValidProps(this._currentElement.props);
|
||||
var closeTag = omittedCloseTags[this._tag] ? '' : '</' + this._tag + '>';
|
||||
return (
|
||||
this._createOpenTagMarkupAndPutListeners(transaction) +
|
||||
this._createContentMarkup(transaction, context) +
|
||||
closeTag
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates markup for the open tag and all attributes.
|
||||
@@ -319,24 +315,20 @@ ReactDOMComponent.Mixin = {
|
||||
* @internal
|
||||
* @overridable
|
||||
*/
|
||||
updateComponent: ReactPerf.measure(
|
||||
'ReactDOMComponent',
|
||||
'updateComponent',
|
||||
function(transaction, prevElement, nextElement, context) {
|
||||
if(context === undefined) throw new Error("Context required for mounting");
|
||||
if(context === null) throw new Error("Assert: context is not null");
|
||||
assertValidProps(this._currentElement.props);
|
||||
ReactComponent.Mixin.updateComponent.call(
|
||||
this,
|
||||
transaction,
|
||||
prevElement,
|
||||
nextElement,
|
||||
context
|
||||
);
|
||||
this._updateDOMProperties(prevElement.props, transaction);
|
||||
this._updateDOMChildren(prevElement.props, transaction, context);
|
||||
}
|
||||
),
|
||||
updateComponent: function(transaction, prevElement, nextElement, context) {
|
||||
if(context === undefined) throw new Error("Context required for mounting");
|
||||
if(context === null) throw new Error("Assert: context is not null");
|
||||
assertValidProps(this._currentElement.props);
|
||||
ReactComponent.Mixin.updateComponent.call(
|
||||
this,
|
||||
transaction,
|
||||
prevElement,
|
||||
nextElement,
|
||||
context
|
||||
);
|
||||
this._updateDOMProperties(prevElement.props, transaction);
|
||||
this._updateDOMChildren(prevElement.props, transaction, context);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reconciles the properties by detecting differences in property values and
|
||||
@@ -504,6 +496,11 @@ ReactDOMComponent.Mixin = {
|
||||
|
||||
};
|
||||
|
||||
ReactPerf.measureMethods(ReactDOMComponent, 'ReactDOMComponent', {
|
||||
mountComponent: 'mountComponent',
|
||||
updateComponent: 'updateComponent'
|
||||
});
|
||||
|
||||
assign(
|
||||
ReactDOMComponent.prototype,
|
||||
ReactComponent.Mixin,
|
||||
|
||||
@@ -50,27 +50,23 @@ var ReactDOMIDOperations = {
|
||||
* @param {*} value New value of the property.
|
||||
* @internal
|
||||
*/
|
||||
updatePropertyByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'updatePropertyByID',
|
||||
function(id, name, value) {
|
||||
var node = ReactMount.getNode(id);
|
||||
invariant(
|
||||
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
||||
'updatePropertyByID(...): %s',
|
||||
INVALID_PROPERTY_ERRORS[name]
|
||||
);
|
||||
updatePropertyByID: function(id, name, value) {
|
||||
var node = ReactMount.getNode(id);
|
||||
invariant(
|
||||
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
||||
'updatePropertyByID(...): %s',
|
||||
INVALID_PROPERTY_ERRORS[name]
|
||||
);
|
||||
|
||||
// If we're updating to null or undefined, we should remove the property
|
||||
// from the DOM node instead of inadvertantly setting to a string. This
|
||||
// brings us in line with the same behavior we have on initial render.
|
||||
if (value != null) {
|
||||
DOMPropertyOperations.setValueForProperty(node, name, value);
|
||||
} else {
|
||||
DOMPropertyOperations.deleteValueForProperty(node, name);
|
||||
}
|
||||
// If we're updating to null or undefined, we should remove the property
|
||||
// from the DOM node instead of inadvertantly setting to a string. This
|
||||
// brings us in line with the same behavior we have on initial render.
|
||||
if (value != null) {
|
||||
DOMPropertyOperations.setValueForProperty(node, name, value);
|
||||
} else {
|
||||
DOMPropertyOperations.deleteValueForProperty(node, name);
|
||||
}
|
||||
),
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a DOM node to remove a property. This should only be used to remove
|
||||
@@ -80,19 +76,15 @@ var ReactDOMIDOperations = {
|
||||
* @param {string} name A property name to remove, see `DOMProperty`.
|
||||
* @internal
|
||||
*/
|
||||
deletePropertyByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'deletePropertyByID',
|
||||
function(id, name, value) {
|
||||
var node = ReactMount.getNode(id);
|
||||
invariant(
|
||||
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
||||
'updatePropertyByID(...): %s',
|
||||
INVALID_PROPERTY_ERRORS[name]
|
||||
);
|
||||
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
||||
}
|
||||
),
|
||||
deletePropertyByID: function(id, name, value) {
|
||||
var node = ReactMount.getNode(id);
|
||||
invariant(
|
||||
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
|
||||
'updatePropertyByID(...): %s',
|
||||
INVALID_PROPERTY_ERRORS[name]
|
||||
);
|
||||
DOMPropertyOperations.deleteValueForProperty(node, name, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a DOM node with new style values. If a value is specified as '',
|
||||
@@ -102,14 +94,10 @@ var ReactDOMIDOperations = {
|
||||
* @param {object} styles Mapping from styles to values.
|
||||
* @internal
|
||||
*/
|
||||
updateStylesByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'updateStylesByID',
|
||||
function(id, styles) {
|
||||
var node = ReactMount.getNode(id);
|
||||
CSSPropertyOperations.setValueForStyles(node, styles);
|
||||
}
|
||||
),
|
||||
updateStylesByID: function(id, styles) {
|
||||
var node = ReactMount.getNode(id);
|
||||
CSSPropertyOperations.setValueForStyles(node, styles);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a DOM node's innerHTML.
|
||||
@@ -118,14 +106,10 @@ var ReactDOMIDOperations = {
|
||||
* @param {string} html An HTML string.
|
||||
* @internal
|
||||
*/
|
||||
updateInnerHTMLByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'updateInnerHTMLByID',
|
||||
function(id, html) {
|
||||
var node = ReactMount.getNode(id);
|
||||
setInnerHTML(node, html);
|
||||
}
|
||||
),
|
||||
updateInnerHTMLByID: function(id, html) {
|
||||
var node = ReactMount.getNode(id);
|
||||
setInnerHTML(node, html);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a DOM node's text content set by `props.content`.
|
||||
@@ -134,14 +118,10 @@ var ReactDOMIDOperations = {
|
||||
* @param {string} content Text content.
|
||||
* @internal
|
||||
*/
|
||||
updateTextContentByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'updateTextContentByID',
|
||||
function(id, content) {
|
||||
var node = ReactMount.getNode(id);
|
||||
DOMChildrenOperations.updateTextContent(node, content);
|
||||
}
|
||||
),
|
||||
updateTextContentByID: function(id, content) {
|
||||
var node = ReactMount.getNode(id);
|
||||
DOMChildrenOperations.updateTextContent(node, content);
|
||||
},
|
||||
|
||||
/**
|
||||
* Replaces a DOM node that exists in the document with markup.
|
||||
@@ -151,14 +131,10 @@ var ReactDOMIDOperations = {
|
||||
* @internal
|
||||
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
|
||||
*/
|
||||
dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'dangerouslyReplaceNodeWithMarkupByID',
|
||||
function(id, markup) {
|
||||
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
|
||||
var node = ReactMount.getNode(id);
|
||||
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
|
||||
}
|
||||
),
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates a component's children by processing a series of updates.
|
||||
@@ -167,16 +143,22 @@ var ReactDOMIDOperations = {
|
||||
* @param {array<string>} markup List of markup strings.
|
||||
* @internal
|
||||
*/
|
||||
dangerouslyProcessChildrenUpdates: ReactPerf.measure(
|
||||
'ReactDOMIDOperations',
|
||||
'dangerouslyProcessChildrenUpdates',
|
||||
function(updates, markup) {
|
||||
for (var i = 0; i < updates.length; i++) {
|
||||
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
||||
}
|
||||
DOMChildrenOperations.processUpdates(updates, markup);
|
||||
dangerouslyProcessChildrenUpdates: function(updates, markup) {
|
||||
for (var i = 0; i < updates.length; i++) {
|
||||
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
|
||||
}
|
||||
)
|
||||
DOMChildrenOperations.processUpdates(updates, markup);
|
||||
}
|
||||
};
|
||||
|
||||
ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
|
||||
updatePropertyByID: 'updatePropertyByID',
|
||||
deletePropertyByID: 'deletePropertyByID',
|
||||
updateStylesByID: 'updateStylesByID',
|
||||
updateInnerHTMLByID: 'updateInnerHTMLByID',
|
||||
updateTextContentByID: 'updateTextContentByID',
|
||||
dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID',
|
||||
dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
|
||||
});
|
||||
|
||||
module.exports = ReactDOMIDOperations;
|
||||
|
||||
@@ -319,50 +319,47 @@ var ReactMount = {
|
||||
* @param {boolean} shouldReuseMarkup if we should skip the markup insertion
|
||||
* @return {ReactComponent} nextComponent
|
||||
*/
|
||||
_renderNewRootComponent: ReactPerf.measure(
|
||||
'ReactMount',
|
||||
'_renderNewRootComponent',
|
||||
function(
|
||||
nextComponent,
|
||||
container,
|
||||
shouldReuseMarkup) {
|
||||
// Various parts of our code (such as ReactCompositeComponent's
|
||||
// _renderValidatedComponent) assume that calls to render aren't nested;
|
||||
// verify that that's the case.
|
||||
warning(
|
||||
ReactCurrentOwner.current == null,
|
||||
'_renderNewRootComponent(): Render methods should be a pure function ' +
|
||||
'of props and state; triggering nested component updates from ' +
|
||||
'render is not allowed. If necessary, trigger nested updates in ' +
|
||||
'componentDidUpdate.'
|
||||
);
|
||||
_renderNewRootComponent: function(
|
||||
nextComponent,
|
||||
container,
|
||||
shouldReuseMarkup
|
||||
) {
|
||||
// Various parts of our code (such as ReactCompositeComponent's
|
||||
// _renderValidatedComponent) assume that calls to render aren't nested;
|
||||
// verify that that's the case.
|
||||
warning(
|
||||
ReactCurrentOwner.current == null,
|
||||
'_renderNewRootComponent(): Render methods should be a pure function ' +
|
||||
'of props and state; triggering nested component updates from ' +
|
||||
'render is not allowed. If necessary, trigger nested updates in ' +
|
||||
'componentDidUpdate.'
|
||||
);
|
||||
|
||||
var componentInstance = instantiateReactComponent(nextComponent, null);
|
||||
var reactRootID = ReactMount._registerComponent(
|
||||
componentInstance,
|
||||
container
|
||||
);
|
||||
var componentInstance = instantiateReactComponent(nextComponent, null);
|
||||
var reactRootID = ReactMount._registerComponent(
|
||||
componentInstance,
|
||||
container
|
||||
);
|
||||
|
||||
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
||||
transaction.perform(
|
||||
mountComponentIntoNode,
|
||||
componentInstance,
|
||||
reactRootID,
|
||||
container,
|
||||
transaction,
|
||||
shouldReuseMarkup
|
||||
);
|
||||
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
||||
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
||||
transaction.perform(
|
||||
mountComponentIntoNode,
|
||||
componentInstance,
|
||||
reactRootID,
|
||||
container,
|
||||
transaction,
|
||||
shouldReuseMarkup
|
||||
);
|
||||
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
||||
|
||||
if (__DEV__) {
|
||||
// Record the root element in case it later gets transplanted.
|
||||
rootElementsByReactRootID[reactRootID] =
|
||||
getReactRootElementInContainer(container);
|
||||
}
|
||||
|
||||
return componentInstance;
|
||||
if (__DEV__) {
|
||||
// Record the root element in case it later gets transplanted.
|
||||
rootElementsByReactRootID[reactRootID] =
|
||||
getReactRootElementInContainer(container);
|
||||
}
|
||||
),
|
||||
|
||||
return componentInstance;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders a React component into the DOM in the supplied `container`.
|
||||
@@ -711,62 +708,58 @@ var ReactMount = {
|
||||
);
|
||||
},
|
||||
|
||||
_mountImageIntoNode: ReactPerf.measure(
|
||||
'ReactMount',
|
||||
'_mountImageIntoNode',
|
||||
function(markup, container, shouldReuseMarkup) {
|
||||
invariant(
|
||||
container && (
|
||||
container.nodeType === ELEMENT_NODE_TYPE ||
|
||||
container.nodeType === DOC_NODE_TYPE
|
||||
),
|
||||
'mountComponentIntoNode(...): Target container is not valid.'
|
||||
);
|
||||
_mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
|
||||
invariant(
|
||||
container && (
|
||||
container.nodeType === ELEMENT_NODE_TYPE ||
|
||||
container.nodeType === DOC_NODE_TYPE
|
||||
),
|
||||
'mountComponentIntoNode(...): Target container is not valid.'
|
||||
);
|
||||
|
||||
if (shouldReuseMarkup) {
|
||||
if (ReactMarkupChecksum.canReuseMarkup(
|
||||
markup,
|
||||
getReactRootElementInContainer(container))) {
|
||||
return;
|
||||
} else {
|
||||
invariant(
|
||||
container.nodeType !== DOC_NODE_TYPE,
|
||||
'You\'re trying to render a component to the document using ' +
|
||||
'server rendering but the checksum was invalid. This usually ' +
|
||||
'means you rendered a different component type or props on ' +
|
||||
'the client from the one on the server, or your render() ' +
|
||||
'methods are impure. React cannot handle this case due to ' +
|
||||
'cross-browser quirks by rendering at the document root. You ' +
|
||||
'should look for environment dependent code in your components ' +
|
||||
'and ensure the props are the same client and server side.'
|
||||
if (shouldReuseMarkup) {
|
||||
if (ReactMarkupChecksum.canReuseMarkup(
|
||||
markup,
|
||||
getReactRootElementInContainer(container))) {
|
||||
return;
|
||||
} else {
|
||||
invariant(
|
||||
container.nodeType !== DOC_NODE_TYPE,
|
||||
'You\'re trying to render a component to the document using ' +
|
||||
'server rendering but the checksum was invalid. This usually ' +
|
||||
'means you rendered a different component type or props on ' +
|
||||
'the client from the one on the server, or your render() ' +
|
||||
'methods are impure. React cannot handle this case due to ' +
|
||||
'cross-browser quirks by rendering at the document root. You ' +
|
||||
'should look for environment dependent code in your components ' +
|
||||
'and ensure the props are the same client and server side.'
|
||||
);
|
||||
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
'React attempted to use reuse markup in a container but the ' +
|
||||
'checksum was invalid. This generally means that you are ' +
|
||||
'using server rendering and the markup generated on the ' +
|
||||
'server was not what the client was expecting. React injected ' +
|
||||
'new markup to compensate which works but you have lost many ' +
|
||||
'of the benefits of server rendering. Instead, figure out ' +
|
||||
'why the markup being generated is different on the client ' +
|
||||
'or server.'
|
||||
);
|
||||
|
||||
if (__DEV__) {
|
||||
console.warn(
|
||||
'React attempted to use reuse markup in a container but the ' +
|
||||
'checksum was invalid. This generally means that you are ' +
|
||||
'using server rendering and the markup generated on the ' +
|
||||
'server was not what the client was expecting. React injected ' +
|
||||
'new markup to compensate which works but you have lost many ' +
|
||||
'of the benefits of server rendering. Instead, figure out ' +
|
||||
'why the markup being generated is different on the client ' +
|
||||
'or server.'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invariant(
|
||||
container.nodeType !== DOC_NODE_TYPE,
|
||||
'You\'re trying to render a component to the document but ' +
|
||||
'you didn\'t use server rendering. We can\'t do this ' +
|
||||
'without using server rendering due to cross-browser quirks. ' +
|
||||
'See renderComponentToString() for server rendering.'
|
||||
);
|
||||
|
||||
setInnerHTML(container, markup);
|
||||
}
|
||||
),
|
||||
|
||||
invariant(
|
||||
container.nodeType !== DOC_NODE_TYPE,
|
||||
'You\'re trying to render a component to the document but ' +
|
||||
'you didn\'t use server rendering. We can\'t do this ' +
|
||||
'without using server rendering due to cross-browser quirks. ' +
|
||||
'See renderComponentToString() for server rendering.'
|
||||
);
|
||||
|
||||
setInnerHTML(container, markup);
|
||||
},
|
||||
|
||||
/**
|
||||
* React ID utilities.
|
||||
@@ -785,6 +778,11 @@ var ReactMount = {
|
||||
purgeID: purgeID
|
||||
};
|
||||
|
||||
ReactPerf.measureMethods(ReactMount, 'ReactMount', {
|
||||
_renderNewRootComponent: '_renderNewRootComponent',
|
||||
_mountImageIntoNode: '_mountImageIntoNode'
|
||||
});
|
||||
|
||||
// Deprecations (remove for 0.13)
|
||||
ReactMount.renderComponent = deprecated(
|
||||
'ReactMount',
|
||||
|
||||
+168
-168
@@ -157,85 +157,81 @@ var ReactCompositeComponentMixin = assign({},
|
||||
* @final
|
||||
* @internal
|
||||
*/
|
||||
mountComponent: ReactPerf.measure(
|
||||
'ReactCompositeComponent',
|
||||
'mountComponent',
|
||||
function(rootID, transaction, mountDepth, context) {
|
||||
invariant(context !== undefined, "Context is required parameter");
|
||||
ReactComponent.Mixin.mountComponent.call(
|
||||
this,
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth,
|
||||
context
|
||||
);
|
||||
mountComponent: function(rootID, transaction, mountDepth, context) {
|
||||
invariant(context !== undefined, "Context is required parameter");
|
||||
ReactComponent.Mixin.mountComponent.call(
|
||||
this,
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth,
|
||||
context
|
||||
);
|
||||
|
||||
this._context = context;
|
||||
this._rootNodeID = rootID;
|
||||
this._context = context;
|
||||
this._rootNodeID = rootID;
|
||||
|
||||
var inst = this._instance;
|
||||
var inst = this._instance;
|
||||
|
||||
// Store a reference from the instance back to the internal representation
|
||||
ReactInstanceMap.set(inst, this);
|
||||
// Store a reference from the instance back to the internal representation
|
||||
ReactInstanceMap.set(inst, this);
|
||||
|
||||
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
||||
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
||||
|
||||
inst.context = this._processContext(this._currentElement._context);
|
||||
if (__DEV__) {
|
||||
this._warnIfContextsDiffer(this._currentElement._context, context);
|
||||
}
|
||||
inst.props = this._processProps(this._currentElement.props);
|
||||
|
||||
var initialState = inst.getInitialState ? inst.getInitialState() : null;
|
||||
if (__DEV__) {
|
||||
// We allow auto-mocks to proceed as if they're returning null.
|
||||
if (typeof initialState === 'undefined' &&
|
||||
inst.getInitialState._isMockFunction) {
|
||||
// This is probably bad practice. Consider warning here and
|
||||
// deprecating this convenience.
|
||||
initialState = null;
|
||||
}
|
||||
}
|
||||
invariant(
|
||||
typeof initialState === 'object' && !Array.isArray(initialState),
|
||||
'%s.getInitialState(): must return an object or null',
|
||||
inst.constructor.displayName || 'ReactCompositeComponent'
|
||||
);
|
||||
inst.state = initialState;
|
||||
|
||||
this._pendingState = null;
|
||||
this._pendingForceUpdate = false;
|
||||
|
||||
if (inst.componentWillMount) {
|
||||
inst.componentWillMount();
|
||||
// When mounting, calls to `setState` by `componentWillMount` will set
|
||||
// `this._pendingState` without triggering a re-render.
|
||||
if (this._pendingState) {
|
||||
inst.state = this._pendingState;
|
||||
this._pendingState = null;
|
||||
}
|
||||
}
|
||||
|
||||
var renderedElement = this._renderValidatedComponent();
|
||||
this._renderedComponent = this._instantiateReactComponent(
|
||||
renderedElement,
|
||||
this._currentElement.type // The wrapping type
|
||||
);
|
||||
|
||||
// Done with mounting, `setState` will now trigger UI changes.
|
||||
this._compositeLifeCycleState = null;
|
||||
var markup = this._renderedComponent.mountComponent(
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth + 1,
|
||||
this._processChildContext(context)
|
||||
);
|
||||
if (inst.componentDidMount) {
|
||||
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
||||
}
|
||||
return markup;
|
||||
inst.context = this._processContext(this._currentElement._context);
|
||||
if (__DEV__) {
|
||||
this._warnIfContextsDiffer(this._currentElement._context, context);
|
||||
}
|
||||
),
|
||||
inst.props = this._processProps(this._currentElement.props);
|
||||
|
||||
var initialState = inst.getInitialState ? inst.getInitialState() : null;
|
||||
if (__DEV__) {
|
||||
// We allow auto-mocks to proceed as if they're returning null.
|
||||
if (typeof initialState === 'undefined' &&
|
||||
inst.getInitialState._isMockFunction) {
|
||||
// This is probably bad practice. Consider warning here and
|
||||
// deprecating this convenience.
|
||||
initialState = null;
|
||||
}
|
||||
}
|
||||
invariant(
|
||||
typeof initialState === 'object' && !Array.isArray(initialState),
|
||||
'%s.getInitialState(): must return an object or null',
|
||||
inst.constructor.displayName || 'ReactCompositeComponent'
|
||||
);
|
||||
inst.state = initialState;
|
||||
|
||||
this._pendingState = null;
|
||||
this._pendingForceUpdate = false;
|
||||
|
||||
if (inst.componentWillMount) {
|
||||
inst.componentWillMount();
|
||||
// When mounting, calls to `setState` by `componentWillMount` will set
|
||||
// `this._pendingState` without triggering a re-render.
|
||||
if (this._pendingState) {
|
||||
inst.state = this._pendingState;
|
||||
this._pendingState = null;
|
||||
}
|
||||
}
|
||||
|
||||
var renderedElement = this._renderValidatedComponent();
|
||||
this._renderedComponent = this._instantiateReactComponent(
|
||||
renderedElement,
|
||||
this._currentElement.type // The wrapping type
|
||||
);
|
||||
|
||||
// Done with mounting, `setState` will now trigger UI changes.
|
||||
this._compositeLifeCycleState = null;
|
||||
var markup = this._renderedComponent.mountComponent(
|
||||
rootID,
|
||||
transaction,
|
||||
mountDepth + 1,
|
||||
this._processChildContext(context)
|
||||
);
|
||||
if (inst.componentDidMount) {
|
||||
transaction.getReactMountReady().enqueue(inst.componentDidMount, inst);
|
||||
}
|
||||
return markup;
|
||||
},
|
||||
|
||||
/**
|
||||
* Releases any resources allocated by `mountComponent`.
|
||||
@@ -627,84 +623,82 @@ var ReactCompositeComponentMixin = assign({},
|
||||
* @internal
|
||||
* @overridable
|
||||
*/
|
||||
updateComponent: ReactPerf.measure(
|
||||
'ReactCompositeComponent',
|
||||
'updateComponent',
|
||||
function(
|
||||
transaction,
|
||||
prevParentElement,
|
||||
nextParentElement,
|
||||
prevUnmaskedContext,
|
||||
nextUnmaskedContext) {
|
||||
// Update refs regardless of what shouldComponentUpdate returns
|
||||
ReactComponent.Mixin.updateComponent.call(
|
||||
this,
|
||||
transaction,
|
||||
prevParentElement,
|
||||
nextParentElement,
|
||||
prevUnmaskedContext,
|
||||
nextUnmaskedContext
|
||||
);
|
||||
updateComponent: function(
|
||||
transaction,
|
||||
prevParentElement,
|
||||
nextParentElement,
|
||||
prevUnmaskedContext,
|
||||
nextUnmaskedContext
|
||||
) {
|
||||
// Update refs regardless of what shouldComponentUpdate returns
|
||||
ReactComponent.Mixin.updateComponent.call(
|
||||
this,
|
||||
transaction,
|
||||
prevParentElement,
|
||||
nextParentElement,
|
||||
prevUnmaskedContext,
|
||||
nextUnmaskedContext
|
||||
);
|
||||
|
||||
var inst = this._instance;
|
||||
var inst = this._instance;
|
||||
|
||||
var prevContext = inst.context;
|
||||
var prevProps = inst.props;
|
||||
var nextContext = prevContext;
|
||||
var nextProps = prevProps;
|
||||
// Distinguish between a props update versus a simple state update
|
||||
if (prevParentElement !== nextParentElement) {
|
||||
nextContext = this._processContext(nextParentElement._context);
|
||||
nextProps = this._processProps(nextParentElement.props);
|
||||
var prevContext = inst.context;
|
||||
var prevProps = inst.props;
|
||||
var nextContext = prevContext;
|
||||
var nextProps = prevProps;
|
||||
// Distinguish between a props update versus a simple state update
|
||||
if (prevParentElement !== nextParentElement) {
|
||||
nextContext = this._processContext(nextParentElement._context);
|
||||
nextProps = this._processProps(nextParentElement.props);
|
||||
|
||||
this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
|
||||
if (inst.componentWillReceiveProps) {
|
||||
inst.componentWillReceiveProps(nextProps, nextContext);
|
||||
}
|
||||
this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
|
||||
if (inst.componentWillReceiveProps) {
|
||||
inst.componentWillReceiveProps(nextProps, nextContext);
|
||||
}
|
||||
}
|
||||
|
||||
this._compositeLifeCycleState = null;
|
||||
this._compositeLifeCycleState = null;
|
||||
|
||||
var nextState = this._pendingState || inst.state;
|
||||
this._pendingState = null;
|
||||
var nextState = this._pendingState || inst.state;
|
||||
this._pendingState = null;
|
||||
|
||||
var shouldUpdate =
|
||||
this._pendingForceUpdate ||
|
||||
!inst.shouldComponentUpdate ||
|
||||
inst.shouldComponentUpdate(nextProps, nextState, nextContext);
|
||||
var shouldUpdate =
|
||||
this._pendingForceUpdate ||
|
||||
!inst.shouldComponentUpdate ||
|
||||
inst.shouldComponentUpdate(nextProps, nextState, nextContext);
|
||||
|
||||
if (__DEV__) {
|
||||
if (typeof shouldUpdate === "undefined") {
|
||||
console.warn(
|
||||
(inst.constructor.displayName || 'ReactCompositeComponent') +
|
||||
'.shouldComponentUpdate(): Returned undefined instead of a ' +
|
||||
'boolean value. Make sure to return true or false.'
|
||||
);
|
||||
}
|
||||
if (__DEV__) {
|
||||
if (typeof shouldUpdate === "undefined") {
|
||||
console.warn(
|
||||
(inst.constructor.displayName || 'ReactCompositeComponent') +
|
||||
'.shouldComponentUpdate(): Returned undefined instead of a ' +
|
||||
'boolean value. Make sure to return true or false.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!shouldUpdate) {
|
||||
// If it's determined that a component should not update, we still want
|
||||
// to set props and state but we shortcut the rest of the update.
|
||||
this._currentElement = nextParentElement;
|
||||
this._context = nextUnmaskedContext;
|
||||
inst.props = nextProps;
|
||||
inst.state = nextState;
|
||||
inst.context = nextContext;
|
||||
return;
|
||||
}
|
||||
if (!shouldUpdate) {
|
||||
// If it's determined that a component should not update, we still want
|
||||
// to set props and state but we shortcut the rest of the update.
|
||||
this._currentElement = nextParentElement;
|
||||
this._context = nextUnmaskedContext;
|
||||
inst.props = nextProps;
|
||||
inst.state = nextState;
|
||||
inst.context = nextContext;
|
||||
return;
|
||||
}
|
||||
|
||||
this._pendingForceUpdate = false;
|
||||
// Will set `this.props`, `this.state` and `this.context`.
|
||||
this._performComponentUpdate(
|
||||
nextParentElement,
|
||||
nextProps,
|
||||
nextState,
|
||||
nextContext,
|
||||
transaction,
|
||||
nextUnmaskedContext
|
||||
);
|
||||
}),
|
||||
this._pendingForceUpdate = false;
|
||||
// Will set `this.props`, `this.state` and `this.context`.
|
||||
this._performComponentUpdate(
|
||||
nextParentElement,
|
||||
nextProps,
|
||||
nextState,
|
||||
nextContext,
|
||||
transaction,
|
||||
nextUnmaskedContext
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Merges new props and state, notifies delegate methods of update and
|
||||
@@ -816,35 +810,31 @@ var ReactCompositeComponentMixin = assign({},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_renderValidatedComponent: ReactPerf.measure(
|
||||
'ReactCompositeComponent',
|
||||
'_renderValidatedComponent',
|
||||
function() {
|
||||
var renderedComponent;
|
||||
var previousContext = ReactContext.current;
|
||||
ReactContext.current = this._processChildContext(
|
||||
this._currentElement._context
|
||||
);
|
||||
ReactCurrentOwner.current = this;
|
||||
var inst = this._instance;
|
||||
try {
|
||||
renderedComponent =
|
||||
this._renderValidatedComponentWithoutOwnerOrContext();
|
||||
} finally {
|
||||
ReactContext.current = previousContext;
|
||||
ReactCurrentOwner.current = null;
|
||||
}
|
||||
invariant(
|
||||
// TODO: An `isValidNode` function would probably be more appropriate
|
||||
renderedComponent === null || renderedComponent === false ||
|
||||
ReactElement.isValidElement(renderedComponent),
|
||||
'%s.render(): A valid ReactComponent must be returned. You may have ' +
|
||||
'returned undefined, an array or some other invalid object.',
|
||||
inst.constructor.displayName || 'ReactCompositeComponent'
|
||||
);
|
||||
return renderedComponent;
|
||||
_renderValidatedComponent: function() {
|
||||
var renderedComponent;
|
||||
var previousContext = ReactContext.current;
|
||||
ReactContext.current = this._processChildContext(
|
||||
this._currentElement._context
|
||||
);
|
||||
ReactCurrentOwner.current = this;
|
||||
var inst = this._instance;
|
||||
try {
|
||||
renderedComponent =
|
||||
this._renderValidatedComponentWithoutOwnerOrContext();
|
||||
} finally {
|
||||
ReactContext.current = previousContext;
|
||||
ReactCurrentOwner.current = null;
|
||||
}
|
||||
),
|
||||
invariant(
|
||||
// TODO: An `isValidNode` function would probably be more appropriate
|
||||
renderedComponent === null || renderedComponent === false ||
|
||||
ReactElement.isValidElement(renderedComponent),
|
||||
'%s.render(): A valid ReactComponent must be returned. You may have ' +
|
||||
'returned undefined, an array or some other invalid object.',
|
||||
inst.constructor.displayName || 'ReactCompositeComponent'
|
||||
);
|
||||
return renderedComponent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Lazily allocates the refs object and stores `component` as `ref`.
|
||||
@@ -1001,6 +991,16 @@ var ShallowMixin = assign({},
|
||||
|
||||
});
|
||||
|
||||
ReactPerf.measureMethods(
|
||||
ReactCompositeComponentMixin,
|
||||
'ReactCompositeComponent',
|
||||
{
|
||||
mountComponent: 'mountComponent',
|
||||
updateComponent: 'updateComponent',
|
||||
_renderValidatedComponent: '_renderValidatedComponent'
|
||||
}
|
||||
);
|
||||
|
||||
var ReactCompositeComponent = {
|
||||
|
||||
LifeCycle: CompositeLifeCycle,
|
||||
|
||||
+22
-21
@@ -159,30 +159,31 @@ function runBatchedUpdates(transaction) {
|
||||
}
|
||||
}
|
||||
|
||||
var flushBatchedUpdates = ReactPerf.measure(
|
||||
'ReactUpdates',
|
||||
'flushBatchedUpdates',
|
||||
function() {
|
||||
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
|
||||
// array and perform any updates enqueued by mount-ready handlers (i.e.,
|
||||
// componentDidUpdate) but we need to check here too in order to catch
|
||||
// updates enqueued by setState callbacks and asap calls.
|
||||
while (dirtyComponents.length || asapEnqueued) {
|
||||
if (dirtyComponents.length) {
|
||||
var transaction = ReactUpdatesFlushTransaction.getPooled();
|
||||
transaction.perform(runBatchedUpdates, null, transaction);
|
||||
ReactUpdatesFlushTransaction.release(transaction);
|
||||
}
|
||||
var flushBatchedUpdates = function() {
|
||||
// ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents
|
||||
// array and perform any updates enqueued by mount-ready handlers (i.e.,
|
||||
// componentDidUpdate) but we need to check here too in order to catch
|
||||
// updates enqueued by setState callbacks and asap calls.
|
||||
while (dirtyComponents.length || asapEnqueued) {
|
||||
if (dirtyComponents.length) {
|
||||
var transaction = ReactUpdatesFlushTransaction.getPooled();
|
||||
transaction.perform(runBatchedUpdates, null, transaction);
|
||||
ReactUpdatesFlushTransaction.release(transaction);
|
||||
}
|
||||
|
||||
if (asapEnqueued) {
|
||||
asapEnqueued = false;
|
||||
var queue = asapCallbackQueue;
|
||||
asapCallbackQueue = CallbackQueue.getPooled();
|
||||
queue.notifyAll();
|
||||
CallbackQueue.release(queue);
|
||||
}
|
||||
if (asapEnqueued) {
|
||||
asapEnqueued = false;
|
||||
var queue = asapCallbackQueue;
|
||||
asapCallbackQueue = CallbackQueue.getPooled();
|
||||
queue.notifyAll();
|
||||
CallbackQueue.release(queue);
|
||||
}
|
||||
}
|
||||
};
|
||||
flushBatchedUpdates = ReactPerf.measure(
|
||||
'ReactUpdates',
|
||||
'flushBatchedUpdates',
|
||||
flushBatchedUpdates
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,26 @@ var ReactPerf = {
|
||||
*/
|
||||
storedMeasure: _noMeasure,
|
||||
|
||||
/**
|
||||
* @param {object} object
|
||||
* @param {string} objectName
|
||||
* @param {object<string>} methodNames
|
||||
*/
|
||||
measureMethods: function(object, objectName, methodNames) {
|
||||
if (__DEV__) {
|
||||
for (var key in methodNames) {
|
||||
if (!methodNames.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
object[key] = ReactPerf.measure(
|
||||
objectName,
|
||||
methodNames[key],
|
||||
object[key]
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Use this to wrap methods you want to measure. Zero overhead in production.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user