1
1
import hoistStatics from 'hoist-non-react-statics'
2
2
import invariant from 'invariant'
3
- import { Component , createElement } from 'react'
3
+ import React , { Component , createElement } from 'react'
4
4
5
5
import Subscription from '../utils/Subscription'
6
+ import { ReactReduxContext } from "./context" ;
6
7
import { storeShape , subscriptionShape } from '../utils/PropTypes'
7
8
8
9
let hotReloadingVersion = 0
9
10
const dummyState = { }
10
11
function noop ( ) { }
11
- function makeSelectorStateful ( sourceSelector , store ) {
12
+ function makeSelectorStateful ( sourceSelector ) {
12
13
// wrap the selector in an object that tracks its results between runs.
13
14
const selector = {
14
- run : function runComponentSelector ( props ) {
15
+ run : function runComponentSelector ( props , storeState ) {
15
16
try {
16
- const nextProps = sourceSelector ( store . getState ( ) , props )
17
+ const nextProps = sourceSelector ( storeState , props )
17
18
if ( nextProps !== selector . props || selector . error ) {
18
19
selector . shouldComponentUpdate = true
19
20
selector . props = nextProps
@@ -78,17 +79,19 @@ export default function connectAdvanced(
78
79
const subscriptionKey = storeKey + 'Subscription'
79
80
const version = hotReloadingVersion ++
80
81
82
+ /*
81
83
const contextTypes = {
82
84
[storeKey]: storeShape,
83
85
[subscriptionKey]: subscriptionShape,
84
86
}
85
87
const childContextTypes = {
86
88
[subscriptionKey]: subscriptionShape,
87
89
}
90
+ */
88
91
89
92
return function wrapWithConnect ( WrappedComponent ) {
90
93
invariant (
91
- typeof WrappedComponent == 'function' ,
94
+ typeof WrappedComponent === 'function' ,
92
95
`You must pass a component to the function returned by ` +
93
96
`${ methodName } . Instead received ${ JSON . stringify ( WrappedComponent ) } `
94
97
)
@@ -117,22 +120,30 @@ export default function connectAdvanced(
117
120
super ( props , context )
118
121
119
122
this . version = version
120
- this . state = { }
123
+ // this.state = {}
121
124
this . renderCount = 0
122
- this . store = props [ storeKey ] || context [ storeKey ]
123
- this . propsMode = Boolean ( props [ storeKey ] )
125
+ //this.store = props[storeKey] || context[storeKey]
126
+ //this.propsMode = Boolean(props[storeKey])
127
+
128
+ this . storeState = null ;
129
+
130
+
124
131
this . setWrappedInstance = this . setWrappedInstance . bind ( this )
132
+ this . renderChild = this . renderChild . bind ( this ) ;
125
133
134
+ /*
126
135
invariant(this.store,
127
136
`Could not find "${storeKey}" in either the context or props of ` +
128
137
`"${displayName}". Either wrap the root component in a <Provider>, ` +
129
138
`or explicitly pass "${storeKey}" as a prop to "${displayName}".`
130
139
)
140
+ */
131
141
132
- this . initSelector ( )
133
- this . initSubscription ( )
142
+ // this.initSelector()
143
+ // this.initSubscription()
134
144
}
135
145
146
+ /*
136
147
getChildContext() {
137
148
// If this component received store from props, its subscription should be transparent
138
149
// to any descendants receiving store+subscription from context; it passes along
@@ -141,6 +152,7 @@ export default function connectAdvanced(
141
152
const subscription = this.propsMode ? null : this.subscription
142
153
return { [subscriptionKey]: subscription || this.context[subscriptionKey] }
143
154
}
155
+ */
144
156
145
157
componentDidMount ( ) {
146
158
if ( ! shouldHandleStateChanges ) return
@@ -151,24 +163,28 @@ export default function connectAdvanced(
151
163
// To handle the case where a child component may have triggered a state change by
152
164
// dispatching an action in its componentWillMount, we have to re-run the select and maybe
153
165
// re-render.
154
- this . subscription . trySubscribe ( )
155
- this . selector . run ( this . props )
166
+ // this.subscription.trySubscribe()
167
+ this . selector . run ( this . props , this . storeState ) ;
156
168
if ( this . selector . shouldComponentUpdate ) this . forceUpdate ( )
157
169
}
158
170
159
- componentWillReceiveProps ( nextProps ) {
160
- this . selector . run ( nextProps )
171
+
172
+ UNSAFE_componentWillReceiveProps ( nextProps ) {
173
+ this . selector . run ( nextProps , this . storeState ) ;
161
174
}
162
175
176
+
177
+
163
178
shouldComponentUpdate ( ) {
164
179
return this . selector . shouldComponentUpdate
165
180
}
166
181
182
+
167
183
componentWillUnmount ( ) {
168
- if ( this . subscription ) this . subscription . tryUnsubscribe ( )
169
- this . subscription = null
184
+ // if (this.subscription) this.subscription.tryUnsubscribe()
185
+ // this.subscription = null
170
186
this . notifyNestedSubs = noop
171
- this . store = null
187
+ // this.store = null
172
188
this . selector . run = noop
173
189
this . selector . shouldComponentUpdate = false
174
190
}
@@ -185,13 +201,22 @@ export default function connectAdvanced(
185
201
this . wrappedInstance = ref
186
202
}
187
203
204
+ /*
188
205
initSelector() {
189
206
const sourceSelector = selectorFactory(this.store.dispatch, selectorFactoryOptions)
190
207
this.selector = makeSelectorStateful(sourceSelector, this.store)
191
208
this.selector.run(this.props)
192
209
}
210
+ */
211
+
212
+ initSelector ( dispatch , storeState ) {
213
+ const sourceSelector = selectorFactory ( dispatch , selectorFactoryOptions )
214
+ this . selector = makeSelectorStateful ( sourceSelector )
215
+ this . selector . run ( this . props , storeState ) ;
216
+ }
193
217
194
218
initSubscription ( ) {
219
+ /*
195
220
if (!shouldHandleStateChanges) return
196
221
197
222
// parentSub's source should match where store came from: props vs. context. A component
@@ -206,6 +231,7 @@ export default function connectAdvanced(
206
231
// listeners logic is changed to not call listeners that have been unsubscribed in the
207
232
// middle of the notification loop.
208
233
this.notifyNestedSubs = this.subscription.notifyNestedSubs.bind(this.subscription)
234
+ */
209
235
}
210
236
211
237
onStateChange ( ) {
@@ -229,23 +255,69 @@ export default function connectAdvanced(
229
255
this . notifyNestedSubs ( )
230
256
}
231
257
258
+ /*
232
259
isSubscribed() {
233
260
return Boolean(this.subscription) && this.subscription.isSubscribed()
234
261
}
262
+ */
235
263
236
264
addExtraProps ( props ) {
237
- if ( ! withRef && ! renderCountProp && ! ( this . propsMode && this . subscription ) ) return props
265
+ //if (!withRef && !renderCountProp && !(this.propsMode && this.subscription)) return props
266
+ if ( ! withRef && ! renderCountProp ) return props ;
267
+
268
+
238
269
// make a shallow copy so that fields added don't leak to the original selector.
239
270
// this is especially important for 'ref' since that's a reference back to the component
240
271
// instance. a singleton memoized selector would then be holding a reference to the
241
272
// instance, preventing the instance from being garbage collected, and that would be bad
242
273
const withExtras = { ...props }
243
274
if ( withRef ) withExtras . ref = this . setWrappedInstance
244
275
if ( renderCountProp ) withExtras [ renderCountProp ] = this . renderCount ++
245
- if ( this . propsMode && this . subscription ) withExtras [ subscriptionKey ] = this . subscription
276
+ // if (this.propsMode && this.subscription) withExtras[subscriptionKey] = this.subscription
246
277
return withExtras
247
278
}
248
279
280
+ renderChild ( providerValue ) {
281
+ const { storeState, dispatch} = providerValue ;
282
+
283
+ this . storeState = storeState ;
284
+
285
+ //console.log(`Running renderChild (${displayName})`, storeState, this.props);
286
+
287
+ if ( this . selector ) {
288
+ this . selector . run ( this . props , storeState ) ;
289
+ }
290
+ else {
291
+ this . initSelector ( dispatch , storeState ) ;
292
+ }
293
+
294
+
295
+
296
+ if ( this . selector . error ) {
297
+ throw this . selector . error
298
+ }
299
+ else if ( this . selector . shouldComponentUpdate ) {
300
+ console . log ( `Re-rendering component (${ displayName } )` , this . selector . props ) ;
301
+ this . selector . shouldComponentUpdate = false ;
302
+ this . renderedElement = createElement ( WrappedComponent , this . addExtraProps ( this . selector . props ) ) ;
303
+ }
304
+ else {
305
+ //console.log(`Returning existing render result (${displayName})`, this.props)
306
+ }
307
+
308
+ return this . renderedElement ;
309
+ }
310
+
311
+ render ( ) {
312
+ return (
313
+ < ReactReduxContext . Consumer >
314
+ { this . renderChild }
315
+ </ ReactReduxContext . Consumer >
316
+ )
317
+ }
318
+
319
+ /*
320
+
249
321
render() {
250
322
const selector = this.selector
251
323
selector.shouldComponentUpdate = false
@@ -256,14 +328,16 @@ export default function connectAdvanced(
256
328
return createElement(WrappedComponent, this.addExtraProps(selector.props))
257
329
}
258
330
}
331
+ */
259
332
}
260
333
261
334
Connect . WrappedComponent = WrappedComponent
262
335
Connect . displayName = displayName
263
- Connect . childContextTypes = childContextTypes
264
- Connect . contextTypes = contextTypes
265
- Connect . propTypes = contextTypes
336
+ // Connect.childContextTypes = childContextTypes
337
+ // Connect.contextTypes = contextTypes
338
+ // Connect.propTypes = contextTypes
266
339
340
+ /*
267
341
if (process.env.NODE_ENV !== 'production') {
268
342
Connect.prototype.componentWillUpdate = function componentWillUpdate() {
269
343
// We are hot reloading!
@@ -290,6 +364,7 @@ export default function connectAdvanced(
290
364
}
291
365
}
292
366
}
367
+ */
293
368
294
369
return hoistStatics ( Connect , WrappedComponent )
295
370
}
0 commit comments