From 144315060116640527b715630d62ed534506287f Mon Sep 17 00:00:00 2001 From: Keyan Zhang Date: Thu, 28 Jul 2016 11:28:01 -0700 Subject: [PATCH 1/2] removed unnecessary state reset --- .../shared/stack/reconciler/ReactCompositeComponent.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js index 8c50058f1db..e774940a426 100644 --- a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js +++ b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js @@ -342,10 +342,6 @@ var ReactCompositeComponentMixin = { this.getName() || 'ReactCompositeComponent' ); - this._pendingStateQueue = null; - this._pendingReplaceState = false; - this._pendingForceUpdate = false; - var markup; if (inst.unstable_handleError) { markup = this.performInitialMountWithErrorHandling( From 4caac21bb0c4bd04c84c2adde9e99a4e12199dbd Mon Sep 17 00:00:00 2001 From: Keyan Zhang Date: Thu, 28 Jul 2016 17:25:35 -0700 Subject: [PATCH 2/2] optimized SFC initial mounting --- .../reconciler/ReactCompositeComponent.js | 118 +++++++++++++++--- 1 file changed, 101 insertions(+), 17 deletions(-) diff --git a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js index e774940a426..593bb354736 100644 --- a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js +++ b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js @@ -34,8 +34,15 @@ var CompositeTypes = { StatelessFunctional: 2, }; -function StatelessComponent(Component) { +function StatelessComponent(Component, props, context, updater) { + this.props = props; + this.context = context; + this.updater = updater; + + this.refs = emptyObject; + this.state = null; } + StatelessComponent.prototype.render = function() { var Component = ReactInstanceMap.get(this)._currentElement.type; var element = Component(this.props, this.context, this.updater); @@ -219,8 +226,8 @@ var ReactCompositeComponentMixin = { ); var renderedElement; - // Support functional components if (!doConstruct && (inst == null || inst.render == null)) { + // is a stateless functional component (SFC) renderedElement = inst; warnIfInvalidElement(Component, renderedElement); invariant( @@ -231,14 +238,33 @@ var ReactCompositeComponentMixin = { 'returned undefined, an array or some other invalid object.', Component.displayName || Component.name || 'Component' ); - inst = new StatelessComponent(Component); + inst = new StatelessComponent( + Component, + publicProps, + publicContext, + updateQueue + ); this._compositeType = CompositeTypes.StatelessFunctional; + + this._instance = inst; + + // Store a reference from the instance back to the internal representation + ReactInstanceMap.set(inst, this); + + // SFC: skip redundant assertions + return this._getMarkupForSFC( + renderedElement, + hostParent, + hostContainerInfo, + transaction, + context + ); + } + + if (isPureComponent(Component)) { + this._compositeType = CompositeTypes.PureClass; } else { - if (isPureComponent(Component)) { - this._compositeType = CompositeTypes.PureClass; - } else { - this._compositeType = CompositeTypes.ImpureClass; - } + this._compositeType = CompositeTypes.ImpureClass; } if (__DEV__) { @@ -345,14 +371,13 @@ var ReactCompositeComponentMixin = { var markup; if (inst.unstable_handleError) { markup = this.performInitialMountWithErrorHandling( - renderedElement, hostParent, hostContainerInfo, transaction, context ); } else { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); + markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context); } if (inst.componentDidMount) { @@ -373,6 +398,31 @@ var ReactCompositeComponentMixin = { return markup; }, + _getMarkupForSFC: function( + renderedElement, + hostParent, + hostContainerInfo, + transaction, + context + ) { + var markup = this.performInitialMountForSFC( + renderedElement, + hostParent, + hostContainerInfo, + transaction, + context + ); + + if (__DEV__) { + if (this._debugID) { + var callback = (component) => ReactInstrumentation.debugTool.onComponentHasMounted(this._debugID); + transaction.getReactMountReady().enqueue(callback, this); + } + } + + return markup; + }, + _constructComponent: function( doConstruct, publicProps, @@ -452,7 +502,6 @@ var ReactCompositeComponentMixin = { }, performInitialMountWithErrorHandling: function( - renderedElement, hostParent, hostContainerInfo, transaction, @@ -461,7 +510,7 @@ var ReactCompositeComponentMixin = { var markup; var checkpoint = transaction.checkpoint(); try { - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); + markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context); } catch (e) { if (__DEV__) { if (this._debugID !== 0) { @@ -481,13 +530,14 @@ var ReactCompositeComponentMixin = { // Try again - we've informed the component about the error, so they can render an error message this time. // If this throws again, the error will bubble up (and can be caught by a higher error boundary). - markup = this.performInitialMount(renderedElement, hostParent, hostContainerInfo, transaction, context); + markup = this.performInitialMount(hostParent, hostContainerInfo, transaction, context); } return markup; }, - performInitialMount: function(renderedElement, hostParent, hostContainerInfo, transaction, context) { + performInitialMount: function(hostParent, hostContainerInfo, transaction, context) { var inst = this._instance; + var renderedElement; if (inst.componentWillMount) { if (__DEV__) { if (this._debugID !== 0) { @@ -513,11 +563,45 @@ var ReactCompositeComponentMixin = { } } - // If not a stateless component, we now render - if (renderedElement === undefined) { - renderedElement = this._renderValidatedComponent(); + renderedElement = this._renderValidatedComponent(); + + var nodeType = ReactNodeTypes.getType(renderedElement); + this._renderedNodeType = nodeType; + var child = this._instantiateReactComponent( + renderedElement, + nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ + ); + this._renderedComponent = child; + if (__DEV__) { + if (child._debugID !== 0 && this._debugID !== 0) { + ReactInstrumentation.debugTool.onSetParent( + child._debugID, + this._debugID + ); + } } + var markup = ReactReconciler.mountComponent( + child, + transaction, + hostParent, + hostContainerInfo, + this._processChildContext(context) + ); + + if (__DEV__) { + if (this._debugID !== 0) { + ReactInstrumentation.debugTool.onSetChildren( + this._debugID, + child._debugID !== 0 ? [child._debugID] : [] + ); + } + } + + return markup; + }, + + performInitialMountForSFC: function(renderedElement, hostParent, hostContainerInfo, transaction, context) { var nodeType = ReactNodeTypes.getType(renderedElement); this._renderedNodeType = nodeType; var child = this._instantiateReactComponent(