@@ -31,6 +31,7 @@ class ReactShallowRenderer {
3131 this . _instance = null ;
3232 this . _newState = null ;
3333 this . _rendered = null ;
34+ this . _rendering = false ;
3435 this . _updater = new Updater ( this ) ;
3536 }
3637
@@ -59,17 +60,16 @@ class ReactShallowRenderer {
5960 element . type ,
6061 ) ;
6162
63+ if ( this . _rendering ) {
64+ return ;
65+ }
66+
67+ this . _rendering = true ;
6268 this . _element = element ;
6369 this . _context = context ;
6470
6571 if ( this . _instance ) {
66- this . _rendered = updateClassComponent (
67- this . _instance ,
68- this . _rendered ,
69- element . props ,
70- this . _newState ,
71- context ,
72- ) ;
72+ this . _updateClassComponent ( element . props , context ) ;
7373 } else {
7474 if ( shouldConstruct ( element . type ) ) {
7575 this . _instance = new element . type ( element . props , context ) ;
@@ -88,17 +88,14 @@ class ReactShallowRenderer {
8888 ReactDebugCurrentFrame . element = null ;
8989 }
9090
91- this . _rendered = mountClassComponent (
92- this . _instance ,
93- element . props ,
94- context ,
95- this . _updater ,
96- ) ;
91+ this . _mountClassComponent ( element . props , context ) ;
9792 } else {
9893 this . _rendered = element . type ( element . props , context ) ;
9994 }
10095 }
10196
97+ this . _rendering = false ;
98+
10299 return this . getRenderOutput ( ) ;
103100 }
104101
@@ -115,6 +112,77 @@ class ReactShallowRenderer {
115112 this . _rendered = null ;
116113 this . _instance = null ;
117114 }
115+
116+ _mountClassComponent ( props , context ) {
117+ this . _instance . context = context ;
118+ this . _instance . props = props ;
119+ this . _instance . state = this . _instance . state || emptyObject ;
120+ this . _instance . updater = this . _updater ;
121+
122+ if ( typeof this . _instance . componentWillMount === 'function' ) {
123+ const beforeState = this . _newState ;
124+
125+ this . _instance . componentWillMount ( ) ;
126+
127+ // setState may have been called during cWM
128+ if ( beforeState !== this . _newState ) {
129+ this . _instance . state = this . _newState || emptyObject ;
130+ }
131+ }
132+
133+ this . _rendered = this . _instance . render ( ) ;
134+
135+ // Calling cDU might lead to problems with host component references.
136+ // Since our components aren't really mounted, refs won't be available.
137+ // if (typeof this._instance.componentDidMount === 'function') {
138+ // this._instance.componentDidMount();
139+ // }
140+ }
141+
142+ _updateClassComponent ( props , context ) {
143+ const oldProps = this . _instance . props ;
144+ const oldState = this . _instance . state ;
145+
146+ if (
147+ oldProps !== props &&
148+ typeof this . _instance . componentWillReceiveProps === 'function'
149+ ) {
150+ this . _instance . componentWillReceiveProps ( props ) ;
151+ }
152+
153+ // Read state after cWRP in case it calls setState
154+ const state = this . _newState || emptyObject ;
155+
156+ if ( typeof this . _instance . shouldComponentUpdate === 'function' ) {
157+ if (
158+ this . _instance . shouldComponentUpdate ( props , state , context ) === false
159+ ) {
160+ this . _instance . context = context ;
161+ this . _instance . props = props ;
162+ this . _instance . state = state ;
163+
164+ return ;
165+ }
166+ }
167+
168+ if ( typeof this . _instance . componentWillUpdate === 'function' ) {
169+ this . _instance . componentWillUpdate ( props , state , context ) ;
170+ }
171+
172+ this . _instance . context = context ;
173+ this . _instance . props = props ;
174+ this . _instance . state = state ;
175+
176+ this . _rendered = this . _instance . render ( ) ;
177+
178+ // The 15.x shallow renderer triggered cDU for setState() calls only.
179+ if (
180+ oldState !== state &&
181+ typeof this . _instance . componentDidUpdate === 'function'
182+ ) {
183+ this . _instance . componentDidUpdate ( oldProps , oldState ) ;
184+ }
185+ }
118186}
119187
120188class Updater {
@@ -158,70 +226,8 @@ function getName(type, instance) {
158226 null ;
159227}
160228
161- function mountClassComponent ( instance , props , context , updater ) {
162- instance . context = context ;
163- instance . props = props ;
164- instance . state = instance . state || emptyObject ;
165- instance . updater = updater ;
166-
167- if ( typeof instance . componentWillMount === 'function' ) {
168- instance . componentWillMount ( ) ;
169- }
170-
171- const rendered = instance . render ( ) ;
172-
173- // Calling cDU might lead to problems with host component references.
174- // Since our components aren't really mounted, refs won't be available.
175- // if (typeof instance.componentDidMount === 'function') {
176- // instance.componentDidMount();
177- // }
178-
179- return rendered ;
180- }
181-
182229function shouldConstruct ( Component ) {
183230 return ! ! ( Component . prototype && Component . prototype . isReactComponent ) ;
184231}
185232
186- function updateClassComponent ( instance , rendered , props , state , context ) {
187- state = state || emptyObject ;
188-
189- const oldProps = instance . props ;
190- const oldState = instance . state ;
191-
192- if (
193- oldProps !== props &&
194- typeof instance . componentWillReceiveProps === 'function'
195- ) {
196- instance . componentWillReceiveProps ( props ) ;
197- }
198-
199- if ( typeof instance . shouldComponentUpdate === 'function' ) {
200- if ( instance . shouldComponentUpdate ( props , state , context ) === false ) {
201- instance . context = context ;
202- instance . props = props ;
203- instance . state = state ;
204-
205- return rendered ;
206- }
207- }
208-
209- if ( typeof instance . componentWillUpdate === 'function' ) {
210- instance . componentWillUpdate ( props , state , context ) ;
211- }
212-
213- instance . context = context ;
214- instance . props = props ;
215- instance . state = state ;
216-
217- rendered = instance . render ( ) ;
218-
219- // The 15.x shallow renderer triggered cDU for setState() calls only.
220- if ( oldState !== state && typeof instance . componentDidUpdate === 'function' ) {
221- instance . componentDidUpdate ( oldProps , oldState ) ;
222- }
223-
224- return rendered ;
225- }
226-
227233module . exports = ReactShallowRenderer ;
0 commit comments