@@ -650,6 +650,25 @@ var ReactCompositeComponentMixin = assign({},
650650 }
651651 } ,
652652
653+ /**
654+ * @private
655+ */
656+ _renderValidatedComponentWithoutOwnerOrContext : function ( ) {
657+ var inst = this . _instance ;
658+ var renderedComponent = inst . render ( ) ;
659+ if ( __DEV__ ) {
660+ // We allow auto-mocks to proceed as if they're returning null.
661+ if ( typeof renderedComponent === 'undefined' &&
662+ inst . render . _isMockFunction ) {
663+ // This is probably bad practice. Consider warning here and
664+ // deprecating this convenience.
665+ renderedComponent = null ;
666+ }
667+ }
668+
669+ return renderedComponent ;
670+ } ,
671+
653672 /**
654673 * @private
655674 */
@@ -665,16 +684,8 @@ var ReactCompositeComponentMixin = assign({},
665684 ReactCurrentOwner . current = this ;
666685 var inst = this . _instance ;
667686 try {
668- renderedComponent = inst . render ( ) ;
669- if ( __DEV__ ) {
670- // We allow auto-mocks to proceed as if they're returning null.
671- if ( typeof renderedComponent === 'undefined' &&
672- inst . render . _isMockFunction ) {
673- // This is probably bad practice. Consider warning here and
674- // deprecating this convenience.
675- renderedComponent = null ;
676- }
677- }
687+ renderedComponent =
688+ this . _renderValidatedComponentWithoutOwnerOrContext ( ) ;
678689 } finally {
679690 ReactContext . current = previousContext ;
680691 ReactCurrentOwner . current = null ;
@@ -734,11 +745,124 @@ var ReactCompositeComponentMixin = assign({},
734745
735746} ) ;
736747
748+ var ShallowMixin = assign ( { } ,
749+ ReactCompositeComponentMixin , {
750+
751+ /**
752+ * Initializes the component, renders markup, and registers event listeners.
753+ *
754+ * @param {string } rootID DOM ID of the root node.
755+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction } transaction
756+ * @param {number } mountDepth number of components in the owner hierarchy
757+ * @return {ReactElement } Shallow rendering of the component.
758+ * @final
759+ * @internal
760+ */
761+ mountComponent : function ( rootID , transaction , mountDepth ) {
762+ ReactComponent . Mixin . mountComponent . call (
763+ this ,
764+ rootID ,
765+ transaction ,
766+ mountDepth
767+ ) ;
768+
769+ var inst = this . _instance ;
770+
771+ // Store a reference from the instance back to the internal representation
772+ ReactInstanceMap . set ( inst , this ) ;
773+
774+ this . _compositeLifeCycleState = CompositeLifeCycle . MOUNTING ;
775+
776+ // No context for shallow-mounted components.
777+ inst . props = this . _processProps ( this . _currentElement . props ) ;
778+
779+ var initialState = inst . getInitialState ? inst . getInitialState ( ) : null ;
780+ if ( __DEV__ ) {
781+ // We allow auto-mocks to proceed as if they're returning null.
782+ if ( typeof initialState === 'undefined' &&
783+ inst . getInitialState . _isMockFunction ) {
784+ // This is probably bad practice. Consider warning here and
785+ // deprecating this convenience.
786+ initialState = null ;
787+ }
788+ }
789+ invariant (
790+ typeof initialState === 'object' && ! Array . isArray ( initialState ) ,
791+ '%s.getInitialState(): must return an object or null' ,
792+ inst . constructor . displayName || 'ReactCompositeComponent'
793+ ) ;
794+ inst . state = initialState ;
795+
796+ this . _pendingState = null ;
797+ this . _pendingForceUpdate = false ;
798+
799+ if ( inst . componentWillMount ) {
800+ inst . componentWillMount ( ) ;
801+ // When mounting, calls to `setState` by `componentWillMount` will set
802+ // `this._pendingState` without triggering a re-render.
803+ if ( this . _pendingState ) {
804+ inst . state = this . _pendingState ;
805+ this . _pendingState = null ;
806+ }
807+ }
808+
809+ // No recursive call to instantiateReactComponent for shallow rendering.
810+ this . _renderedComponent =
811+ this . _renderValidatedComponentWithoutOwnerOrContext ( ) ;
812+
813+ // Done with mounting, `setState` will now trigger UI changes.
814+ this . _compositeLifeCycleState = null ;
815+
816+ // No call to this._renderedComponent.mountComponent for shallow
817+ // rendering.
818+
819+ if ( inst . componentDidMount ) {
820+ transaction . getReactMountReady ( ) . enqueue ( inst . componentDidMount , inst ) ;
821+ }
822+
823+ return this . _renderedComponent ;
824+ } ,
825+
826+ /**
827+ * Call the component's `render` method and update the DOM accordingly.
828+ *
829+ * @param {ReactReconcileTransaction } transaction
830+ * @internal
831+ */
832+ _updateRenderedComponent : function ( transaction ) {
833+ var prevComponentInstance = this . _renderedComponent ;
834+ var prevRenderedElement = prevComponentInstance . _currentElement ;
835+ // Use the without-owner-or-context variant of _rVC below:
836+ var nextRenderedElement = this . _renderValidatedComponentWithoutOwnerOrContext ( ) ;
837+ if ( shouldUpdateReactComponent ( prevRenderedElement , nextRenderedElement ) ) {
838+ prevComponentInstance . receiveComponent (
839+ nextRenderedElement ,
840+ transaction
841+ ) ;
842+ } else {
843+ // These two IDs are actually the same! But nothing should rely on that.
844+ var thisID = this . _rootNodeID ;
845+ var prevComponentID = prevComponentInstance . _rootNodeID ;
846+ // Don't unmount previous instance since it was never mounted, due to
847+ // shallow render.
848+ //prevComponentInstance.unmountComponent();
849+ this . _renderedComponent = nextRenderedElement ;
850+ // ^ no instantiateReactComponent
851+ //
852+ // no recursive mountComponent
853+ return nextRenderedElement ;
854+ }
855+ }
856+
857+ } ) ;
858+
737859var ReactCompositeComponent = {
738860
739861 LifeCycle : CompositeLifeCycle ,
740862
741- Mixin : ReactCompositeComponentMixin
863+ Mixin : ReactCompositeComponentMixin ,
864+
865+ ShallowMixin : ShallowMixin
742866
743867} ;
744868
0 commit comments