@@ -87,24 +87,41 @@ export default function connectAdvanced(
87
87
88
88
const displayName = getDisplayName ( wrappedComponentName )
89
89
90
- class PureWrapper extends Component {
91
- shouldComponentUpdate ( nextProps ) {
92
- return nextProps . derivedProps !== this . props . derivedProps
93
- }
90
+ let PureWrapper
94
91
95
- render ( ) {
96
- let { forwardRef, derivedProps } = this . props
97
- return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
92
+ if ( withRef ) {
93
+ class PureWrapperRef extends Component {
94
+ shouldComponentUpdate ( nextProps ) {
95
+ return nextProps . derivedProps !== this . props . derivedProps
96
+ }
97
+
98
+ render ( ) {
99
+ let { forwardRef, derivedProps } = this . props
100
+ return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
101
+ }
98
102
}
99
- }
103
+ PureWrapperRef . propTypes = {
104
+ derivedProps : propTypes . object ,
105
+ forwardRef : propTypes . oneOfType ( [
106
+ propTypes . func ,
107
+ propTypes . object
108
+ ] )
109
+ }
110
+ PureWrapper = PureWrapperRef
111
+ } else {
112
+ class PureWrapperNoRef extends Component {
113
+ shouldComponentUpdate ( nextProps ) {
114
+ return nextProps . derivedProps !== this . props . derivedProps
115
+ }
100
116
101
- PureWrapper . propTypes = {
102
- count : propTypes . object ,
103
- derivedProps : propTypes . object ,
104
- forwardRef : propTypes . oneOfType ( [
105
- propTypes . func ,
106
- propTypes . object
107
- ] )
117
+ render ( ) {
118
+ return < WrappedComponent { ...this . props . derivedProps } />
119
+ }
120
+ }
121
+ PureWrapperNoRef . propTypes = {
122
+ derivedProps : propTypes . object ,
123
+ }
124
+ PureWrapper = PureWrapperNoRef
108
125
}
109
126
110
127
const selectorFactoryOptions = {
@@ -125,48 +142,31 @@ export default function connectAdvanced(
125
142
class Connect extends OuterBase {
126
143
constructor ( props ) {
127
144
super ( props )
128
- if ( withRef ) {
129
- invariant ( ! props . props [ storeKey ] ,
130
- 'Passing redux store in props has been removed and does not do anything. ' +
131
- 'To use a custom redux store for a single component, ' +
132
- 'create a custom React context with React.createContext() and pass the Provider to react-redux\'s provider ' +
133
- 'and the Consumer to this component as in <Provider context={context.Provider}><' +
134
- wrappedComponentName + ' consumer={context.Consumer} /></Provider>'
135
- )
136
- } else {
137
- invariant ( ! props [ storeKey ] ,
138
- 'Passing redux store in props has been removed and does not do anything. ' +
139
- 'To use a custom redux store for a single component, ' +
140
- 'create a custom React context with React.createContext() and pass the Provider to react-redux\'s provider ' +
141
- 'and the Consumer to this component as in <Provider context={context.Provider}><' +
142
- wrappedComponentName + ' consumer={context.Consumer} /></Provider>'
143
- )
144
-
145
- }
146
- this . memoizeDerivedProps = this . makeMemoizer ( )
145
+ invariant ( withRef ? ! props . props [ storeKey ] : ! props [ storeKey ] ,
146
+ 'Passing redux store in props has been removed and does not do anything. ' +
147
+ 'To use a custom redux store for a single component, ' +
148
+ 'create a custom React context with React.createContext() and pass the Provider to react-redux\'s provider ' +
149
+ 'and the Consumer to this component as in <Provider context={context.Provider}><' +
150
+ wrappedComponentName + ' consumer={context.Consumer} /></Provider>'
151
+ )
152
+ this . generatedDerivedProps = this . makeDerivedPropsGenerator ( )
147
153
this . renderWrappedComponent = this . renderWrappedComponent . bind ( this )
148
154
}
149
155
150
- makeMemoizer ( ) {
156
+ makeDerivedPropsGenerator ( ) {
151
157
let lastProps
152
158
let lastState
153
159
let lastDerivedProps
154
160
let lastStore
155
161
let sourceSelector
156
- let called = false
157
162
return ( state , props , store ) => {
158
- if ( called ) {
159
- const sameProps = connectOptions . pure && lastProps === props
160
- const sameState = lastState === state
161
- if ( sameProps && sameState ) {
162
- return lastDerivedProps
163
- }
163
+ if ( ( connectOptions . pure && lastProps === props ) && ( lastState === state ) ) {
164
+ return lastDerivedProps
164
165
}
165
166
if ( store !== lastStore ) {
166
167
lastStore = store
167
168
sourceSelector = selectorFactory ( store . dispatch , selectorFactoryOptions )
168
169
}
169
- called = true
170
170
lastProps = props
171
171
lastState = state
172
172
const nextProps = sourceSelector ( state , props )
@@ -178,24 +178,32 @@ export default function connectAdvanced(
178
178
}
179
179
}
180
180
181
- renderWrappedComponent ( value ) {
181
+ renderWrappedComponentWithRef ( value ) {
182
182
invariant ( value ,
183
183
`Could not find "store" in the context of ` +
184
184
`"${ displayName } ". Either wrap the root component in a <Provider>, ` +
185
185
`or pass a custom React context provider to <Provider> and the corresponding ` +
186
186
`React context consumer to ${ displayName } in connect options.`
187
187
)
188
188
const { state, store } = value
189
- if ( withRef ) {
190
- const { forwardRef, props } = this . props
191
- let derivedProps = this . memoizeDerivedProps ( state , props , store )
192
- if ( connectOptions . pure ) {
193
- return < PureWrapper derivedProps = { derivedProps } forwardRef = { forwardRef } />
194
- }
195
-
196
- return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
189
+ const { forwardRef, props } = this . props
190
+ let derivedProps = this . generatedDerivedProps ( state , props , store )
191
+ if ( connectOptions . pure ) {
192
+ return < PureWrapper derivedProps = { derivedProps } forwardRef = { forwardRef } />
197
193
}
198
- let derivedProps = this . memoizeDerivedProps ( state , this . props , store )
194
+
195
+ return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
196
+ }
197
+
198
+ renderWrappedComponent ( value ) {
199
+ invariant ( value ,
200
+ `Could not find "store" in the context of ` +
201
+ `"${ displayName } ". Either wrap the root component in a <Provider>, ` +
202
+ `or pass a custom React context provider to <Provider> and the corresponding ` +
203
+ `React context consumer to ${ displayName } in connect options.`
204
+ )
205
+ const { state, store } = value
206
+ let derivedProps = this . generatedDerivedProps ( state , this . props , store )
199
207
if ( connectOptions . pure ) {
200
208
return < PureWrapper derivedProps = { derivedProps } />
201
209
}
@@ -215,6 +223,7 @@ export default function connectAdvanced(
215
223
Connect . WrappedComponent = WrappedComponent
216
224
Connect . displayName = displayName
217
225
if ( withRef ) {
226
+ Connect . prototype . renderWrappedComponent = Connect . prototype . renderWrappedComponentWithRef
218
227
Connect . propTypes = {
219
228
props : propTypes . object ,
220
229
forwardRef : propTypes . oneOfType ( [
0 commit comments