1
1
// TODO: deprecate all places where we check if _.isPlainObject
2
2
// TODO: deprecate getItemValue prop
3
3
// TODO: deprecate getItemLabel prop
4
+ // TODO: Add initialValue prop
4
5
import _ from 'lodash' ;
5
6
import PropTypes from 'prop-types' ;
6
7
import React , { Component } from 'react' ;
@@ -162,10 +163,10 @@ class Picker extends Component {
162
163
super ( props ) ;
163
164
164
165
this . state = {
165
- value : props . value ,
166
- prevValue : undefined ,
167
166
selectedItemPosition : 0 ,
168
- items : Picker . extractPickerItems ( props )
167
+ items : Picker . extractPickerItems ( props ) ,
168
+ multiDraftValue : props . value ,
169
+ multiFinalValue : props . value
169
170
} ;
170
171
171
172
if ( props . mode === Picker . modes . SINGLE && Array . isArray ( props . value ) ) {
@@ -186,26 +187,10 @@ class Picker extends Component {
186
187
}
187
188
188
189
static getDerivedStateFromProps ( nextProps , prevState ) {
189
- const hasNextValue = ! _ . isEmpty ( nextProps . value ) || _ . isNumber ( nextProps . value ) ;
190
- /* Relevant for keeping the value prop controlled - react when user change value prop */
191
- const externalValueChanged = hasNextValue && prevState . value !== nextProps . value ;
192
- /* Relevant for multi select mode when we keep an internal value state */
193
- const internalValueChanged = prevState . value !== prevState . prevValue ;
194
- if ( internalValueChanged && nextProps . mode === Picker . modes . MULTI ) {
195
- /* for this.setState() updates to 'value'
196
- NOTE: this.setState() already updated the 'value' so here we only updating the 'prevValue' */
197
- return {
198
- prevValue : prevState . value
199
- } ;
200
- } else if ( externalValueChanged ) {
201
- return {
202
- value : nextProps . value
203
- } ;
204
- } else if ( _ . isFunction ( nextProps . renderPicker ) && externalValueChanged ) {
205
- return {
206
- prevValue : prevState . value ,
207
- value : nextProps . value
208
- } ;
190
+ if ( nextProps . mode === Picker . modes . MULTI ) {
191
+ if ( prevState . multiFinalValue !== nextProps . value ) {
192
+ return { multiDraftValue : nextProps . value , multiFinalValue : nextProps . value } ;
193
+ }
209
194
}
210
195
return null ;
211
196
}
@@ -230,12 +215,12 @@ class Picker extends Component {
230
215
}
231
216
232
217
getContextValue = ( ) => {
233
- const { value } = this . state ;
234
- const { migrate, mode, getItemValue, getItemLabel, renderItem, selectionLimit} = this . props ;
218
+ const { multiDraftValue } = this . state ;
219
+ const { migrate, mode, getItemValue, getItemLabel, renderItem, selectionLimit, value } = this . props ;
235
220
const pickerValue = ! migrate && _ . isPlainObject ( value ) ? value ?. value : value ;
236
221
return {
237
222
migrate,
238
- value : pickerValue ,
223
+ value : mode === Picker . modes . MULTI ? multiDraftValue : pickerValue ,
239
224
onPress : mode === Picker . modes . MULTI ? this . toggleItemSelection : this . onDoneSelecting ,
240
225
isMultiMode : mode === Picker . modes . MULTI ,
241
226
getItemValue,
@@ -314,27 +299,27 @@ class Picker extends Component {
314
299
} ;
315
300
316
301
toggleItemSelection = item => {
317
- const { getItemValue} = this . props ;
318
- const { value } = this . state ;
302
+ const { getItemValue, migrate } = this . props ;
303
+ const { multiDraftValue } = this . state ;
319
304
let newValue ;
320
- if ( _ . isPlainObject ( value ) ) {
321
- newValue = _ . xorBy ( value , [ item ] , getItemValue || 'value' ) ;
305
+ if ( ! migrate ) {
306
+ newValue = _ . xorBy ( multiDraftValue , [ item ] , getItemValue || 'value' ) ;
322
307
} else {
323
- newValue = _ . xor ( value , [ item ] ) ;
308
+ newValue = _ . xor ( multiDraftValue , [ item ] ) ;
324
309
}
325
310
326
- this . setState ( { value : newValue } ) ;
311
+ this . setState ( { multiDraftValue : newValue } ) ;
327
312
} ;
328
313
329
314
cancelSelect = ( ) => {
330
- this . setState ( { value : this . props . value } ) ;
315
+ this . setState ( { multiDraftValue : this . state . multiFinalValue } ) ;
331
316
this . toggleExpandableModal ( false ) ;
332
317
_ . invoke ( this . props , 'topBarProps.onCancel' ) ;
333
318
} ;
334
319
335
320
onDoneSelecting = item => {
336
321
this . clearSearchField ( ) ;
337
- this . setState ( { value : item } ) ;
322
+ this . setState ( { multiFinalValue : item } ) ;
338
323
this . toggleExpandableModal ( false ) ;
339
324
_ . invoke ( this . props , 'onChange' , item ) ;
340
325
} ;
@@ -372,15 +357,15 @@ class Picker extends Component {
372
357
testID,
373
358
pickerModalProps
374
359
} = this . props ;
375
- const { showExpandableModal, selectedItemPosition, value } = this . state ;
360
+ const { showExpandableModal, selectedItemPosition, multiDraftValue } = this . state ;
376
361
377
362
if ( renderCustomModal ) {
378
363
const modalProps = {
379
364
visible : showExpandableModal ,
380
365
toggleModal : this . toggleExpandableModal ,
381
366
onSearchChange : this . onSearchChange ,
382
367
children,
383
- onDone : ( ) => this . onDoneSelecting ( value ) ,
368
+ onDone : ( ) => this . onDoneSelecting ( multiDraftValue ) ,
384
369
onCancel : this . cancelSelect
385
370
} ;
386
371
@@ -403,7 +388,7 @@ class Picker extends Component {
403
388
topBarProps = { {
404
389
...topBarProps ,
405
390
onCancel : this . cancelSelect ,
406
- onDone : mode === Picker . modes . MULTI ? ( ) => this . onDoneSelecting ( value ) : undefined
391
+ onDone : mode === Picker . modes . MULTI ? ( ) => this . onDoneSelecting ( multiDraftValue ) : undefined
407
392
} }
408
393
showSearch = { showSearch }
409
394
searchStyle = { searchStyle }
@@ -429,7 +414,7 @@ class Picker extends Component {
429
414
}
430
415
431
416
if ( _ . isFunction ( renderPicker ) ) {
432
- const { value} = this . state ;
417
+ const { value} = this . props ;
433
418
434
419
return (
435
420
< View left >
0 commit comments