@@ -91,43 +91,6 @@ export default function connectAdvanced(
91
91
92
92
const displayName = getDisplayName ( wrappedComponentName )
93
93
94
- let PureWrapper
95
-
96
- if ( forwardRef ) {
97
- class PureWrapperRef extends Component {
98
- shouldComponentUpdate ( nextProps ) {
99
- return nextProps . derivedProps !== this . props . derivedProps
100
- }
101
-
102
- render ( ) {
103
- let { forwardRef, derivedProps } = this . props
104
- return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
105
- }
106
- }
107
- PureWrapperRef . propTypes = {
108
- //derivedProps: propTypes.object,
109
- forwardRef : propTypes . oneOfType ( [
110
- propTypes . func ,
111
- propTypes . object
112
- ] )
113
- }
114
- PureWrapper = PureWrapperRef
115
- } else {
116
- class PureWrapperNoRef extends Component {
117
- shouldComponentUpdate ( nextProps ) {
118
- return nextProps . derivedProps !== this . props . derivedProps
119
- }
120
-
121
- render ( ) {
122
- return < WrappedComponent { ...this . props . derivedProps } />
123
- }
124
- }
125
- PureWrapperNoRef . propTypes = {
126
- //derivedProps: propTypes.object,
127
- }
128
- PureWrapper = PureWrapperNoRef
129
- }
130
-
131
94
const selectorFactoryOptions = {
132
95
...connectOptions ,
133
96
getDisplayName,
@@ -140,58 +103,81 @@ export default function connectAdvanced(
140
103
WrappedComponent
141
104
}
142
105
143
- const OuterBase = connectOptions . pure ? PureComponent : Component
106
+ const { pure } = connectOptions
144
107
145
- class Connect extends OuterBase {
146
- constructor ( props ) {
147
- super ( props )
148
- invariant ( forwardRef ? ! props . props [ storeKey ] : ! props [ storeKey ] ,
149
- 'Passing redux store in props has been removed and does not do anything. ' + customStoreWarningMessage
150
- )
151
- this . generatedDerivedProps = this . makeDerivedPropsGenerator ( )
152
- this . renderWrappedComponent = this . renderWrappedComponent . bind ( this )
108
+ let OuterBaseComponent = Component
109
+ let FinalWrappedComponent = WrappedComponent
110
+
111
+ if ( pure ) {
112
+ OuterBaseComponent = PureComponent
113
+ //FinalWrappedComponent = React.memo(WrappedComponent)
114
+ }
115
+
116
+ class PureWrapper extends Component {
117
+ shouldComponentUpdate ( nextProps ) {
118
+ return nextProps . derivedProps !== this . props . derivedProps
153
119
}
154
120
155
- makeDerivedPropsGenerator ( ) {
156
- let lastProps
157
- let lastState
158
- let lastDerivedProps
159
- let lastStore
160
- let sourceSelector
161
- return ( state , props , store ) => {
162
- if ( ( connectOptions . pure && lastProps === props ) && ( lastState === state ) ) {
163
- return lastDerivedProps
164
- }
165
- if ( store !== lastStore ) {
166
- lastStore = store
167
- sourceSelector = selectorFactory ( store . dispatch , selectorFactoryOptions )
168
- }
169
- lastProps = props
170
- lastState = state
171
- const nextProps = sourceSelector ( state , props )
172
- if ( lastDerivedProps === nextProps ) {
173
- return lastDerivedProps
174
- }
175
- lastDerivedProps = nextProps
121
+ render ( ) {
122
+ let { forwardedRef, derivedProps } = this . props
123
+ return < WrappedComponent { ...derivedProps } ref = { forwardedRef } />
124
+ }
125
+ }
126
+
127
+ function makeDerivedPropsSelector ( ) {
128
+ let lastProps
129
+ let lastState
130
+ let lastDerivedProps
131
+ let lastStore
132
+ let sourceSelector
133
+
134
+ return function selectDerivedProps ( state , props , store ) {
135
+ if ( ( pure && lastProps === props ) && ( lastState === state ) ) {
136
+ return lastDerivedProps
137
+ }
138
+
139
+ if ( store !== lastStore ) {
140
+ lastStore = store
141
+ sourceSelector = selectorFactory ( store . dispatch , selectorFactoryOptions )
142
+ }
143
+
144
+ lastProps = props
145
+ lastState = state
146
+
147
+ const nextProps = sourceSelector ( state , props )
148
+
149
+ if ( lastDerivedProps === nextProps ) {
176
150
return lastDerivedProps
177
151
}
152
+
153
+ lastDerivedProps = nextProps
154
+ return lastDerivedProps
178
155
}
156
+ }
179
157
180
- renderWrappedComponentWithRef ( value ) {
181
- invariant ( value ,
182
- `Could not find "store" in the context of ` +
183
- `"${ displayName } ". Either wrap the root component in a <Provider>, ` +
184
- `or pass a custom React context provider to <Provider> and the corresponding ` +
185
- `React context consumer to ${ displayName } in connect options.`
186
- )
187
- const { storeState, store } = value
188
- const { forwardRef, props } = this . props
189
- let derivedProps = this . generatedDerivedProps ( storeState , props , store )
190
- if ( connectOptions . pure ) {
191
- return < PureWrapper derivedProps = { derivedProps } forwardRef = { forwardRef } />
158
+ function makeChildElementSelector ( ) {
159
+ let lastChildProps , lastForwardRef , lastChildElement
160
+
161
+ return function selectChildElement ( childProps , forwardRef ) {
162
+ if ( childProps !== lastChildProps || forwardRef !== lastForwardRef ) {
163
+ lastChildProps = childProps
164
+ lastForwardRef = forwardRef
165
+ lastChildElement = < FinalWrappedComponent { ...childProps } ref = { forwardRef } />
192
166
}
193
167
194
- return < WrappedComponent { ...derivedProps } ref = { forwardRef } />
168
+ return lastChildElement
169
+ }
170
+ }
171
+
172
+ class Connect extends OuterBaseComponent {
173
+ constructor ( props ) {
174
+ super ( props )
175
+ invariant ( forwardRef ? ! props . wrapperProps [ storeKey ] : ! props [ storeKey ] ,
176
+ 'Passing redux store in props has been removed and does not do anything. ' + customStoreWarningMessage
177
+ )
178
+ this . selectDerivedProps = makeDerivedPropsSelector ( )
179
+ this . selectChildElement = makeChildElementSelector ( )
180
+ this . renderWrappedComponent = this . renderWrappedComponent . bind ( this )
195
181
}
196
182
197
183
renderWrappedComponent ( value ) {
@@ -202,12 +188,22 @@ export default function connectAdvanced(
202
188
`React context consumer to ${ displayName } in connect options.`
203
189
)
204
190
const { storeState, store } = value
205
- let derivedProps = this . generatedDerivedProps ( storeState , this . props , store )
206
- if ( connectOptions . pure ) {
207
- return < PureWrapper derivedProps = { derivedProps } />
191
+
192
+ let wrapperProps = this . props
193
+ let forwardedRef
194
+
195
+ if ( forwardRef ) {
196
+ wrapperProps = this . props . wrapperProps
197
+ forwardedRef = this . props . forwardedRef
208
198
}
209
199
210
- return < WrappedComponent { ...derivedProps } />
200
+ let derivedProps = this . selectDerivedProps ( storeState , wrapperProps , store )
201
+
202
+ if ( pure ) {
203
+ return this . selectChildElement ( derivedProps , forwardedRef ) ;
204
+ }
205
+
206
+ return < FinalWrappedComponent { ...derivedProps } ref = { forwardedRef } />
211
207
}
212
208
213
209
render ( ) {
@@ -221,28 +217,17 @@ export default function connectAdvanced(
221
217
222
218
Connect . WrappedComponent = WrappedComponent
223
219
Connect . displayName = displayName
224
- if ( forwardRef ) {
225
- Connect . prototype . renderWrappedComponent = Connect . prototype . renderWrappedComponentWithRef
226
- Connect . propTypes = {
227
- props : propTypes . object ,
228
- forwardRef : propTypes . oneOfType ( [
229
- propTypes . func ,
230
- propTypes . object
231
- ] )
232
- }
233
- }
234
220
235
- if ( ! forwardRef ) {
236
- return hoistStatics ( Connect , WrappedComponent )
237
- }
221
+ if ( forwardRef ) {
222
+ const forwarded = React . forwardRef ( function forwardConnectRef ( props , ref ) {
223
+ return < Connect wrapperProps = { props } forwardedRef = { ref } />
224
+ } )
238
225
239
- function forwardRef ( props , ref ) {
240
- return < Connect props = { props } forwardRef = { ref } />
226
+ forwarded . displayName = displayName
227
+ forwarded . WrappedComponent = WrappedComponent
228
+ return hoistStatics ( forwarded , WrappedComponent )
241
229
}
242
230
243
- const forwarded = React . forwardRef ( forwardRef )
244
- forwarded . displayName = displayName
245
- forwarded . WrappedComponent = WrappedComponent
246
- return hoistStatics ( forwarded , WrappedComponent )
231
+ return hoistStatics ( Connect , WrappedComponent )
247
232
}
248
233
}
0 commit comments