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
// TODO: consider deprecating renderCustomModal prop
5
6
// TODO: deprecate onShow cause it's already supported by passing it in pickerModalProps
6
7
import _ from 'lodash' ;
@@ -168,10 +169,10 @@ class Picker extends Component {
168
169
super ( props ) ;
169
170
170
171
this . state = {
171
- value : props . value ,
172
- prevValue : undefined ,
173
172
selectedItemPosition : 0 ,
174
- items : Picker . extractPickerItems ( props )
173
+ items : Picker . extractPickerItems ( props ) ,
174
+ multiDraftValue : props . value ,
175
+ multiFinalValue : props . value
175
176
} ;
176
177
177
178
if ( props . mode === Picker . modes . SINGLE && Array . isArray ( props . value ) ) {
@@ -192,26 +193,10 @@ class Picker extends Component {
192
193
}
193
194
194
195
static getDerivedStateFromProps ( nextProps , prevState ) {
195
- const hasNextValue = ! _ . isEmpty ( nextProps . value ) || _ . isNumber ( nextProps . value ) ;
196
- /* Relevant for keeping the value prop controlled - react when user change value prop */
197
- const externalValueChanged = hasNextValue && prevState . value !== nextProps . value ;
198
- /* Relevant for multi select mode when we keep an internal value state */
199
- const internalValueChanged = prevState . value !== prevState . prevValue ;
200
- if ( internalValueChanged && nextProps . mode === Picker . modes . MULTI ) {
201
- /* for this.setState() updates to 'value'
202
- NOTE: this.setState() already updated the 'value' so here we only updating the 'prevValue' */
203
- return {
204
- prevValue : prevState . value
205
- } ;
206
- } else if ( externalValueChanged ) {
207
- return {
208
- value : nextProps . value
209
- } ;
210
- } else if ( _ . isFunction ( nextProps . renderPicker ) && externalValueChanged ) {
211
- return {
212
- prevValue : prevState . value ,
213
- value : nextProps . value
214
- } ;
196
+ if ( nextProps . mode === Picker . modes . MULTI ) {
197
+ if ( prevState . multiFinalValue !== nextProps . value ) {
198
+ return { multiDraftValue : nextProps . value , multiFinalValue : nextProps . value } ;
199
+ }
215
200
}
216
201
return null ;
217
202
}
@@ -236,12 +221,12 @@ class Picker extends Component {
236
221
}
237
222
238
223
getContextValue = ( ) => {
239
- const { value } = this . state ;
240
- const { migrate, mode, getItemValue, getItemLabel, renderItem, selectionLimit} = this . props ;
224
+ const { multiDraftValue } = this . state ;
225
+ const { migrate, mode, getItemValue, getItemLabel, renderItem, selectionLimit, value } = this . props ;
241
226
const pickerValue = ! migrate && _ . isPlainObject ( value ) ? value ?. value : value ;
242
227
return {
243
228
migrate,
244
- value : pickerValue ,
229
+ value : mode === Picker . modes . MULTI ? multiDraftValue : pickerValue ,
245
230
onPress : mode === Picker . modes . MULTI ? this . toggleItemSelection : this . onDoneSelecting ,
246
231
isMultiMode : mode === Picker . modes . MULTI ,
247
232
getItemValue,
@@ -320,28 +305,28 @@ class Picker extends Component {
320
305
// };
321
306
322
307
toggleItemSelection = item => {
323
- const { getItemValue} = this . props ;
324
- const { value } = this . state ;
308
+ const { getItemValue, migrate } = this . props ;
309
+ const { multiDraftValue } = this . state ;
325
310
let newValue ;
326
- if ( _ . isPlainObject ( value ) ) {
327
- newValue = _ . xorBy ( value , [ item ] , getItemValue || 'value' ) ;
311
+ if ( ! migrate ) {
312
+ newValue = _ . xorBy ( multiDraftValue , [ item ] , getItemValue || 'value' ) ;
328
313
} else {
329
- newValue = _ . xor ( value , [ item ] ) ;
314
+ newValue = _ . xor ( multiDraftValue , [ item ] ) ;
330
315
}
331
316
332
- this . setState ( { value : newValue } ) ;
317
+ this . setState ( { multiDraftValue : newValue } ) ;
333
318
} ;
334
319
335
320
cancelSelect = ( ) => {
336
- this . setState ( { value : this . props . value } ) ;
321
+ this . setState ( { multiDraftValue : this . state . multiFinalValue } ) ;
337
322
// this.toggleExpandableModal(false);
338
323
this . pickerExpandable . current ?. closeExpandable ?. ( ) ;
339
324
this . props . topBarProps ?. onCancel ?. ( ) ;
340
325
} ;
341
326
342
327
onDoneSelecting = item => {
343
328
this . clearSearchField ( ) ;
344
- this . setState ( { value : item } ) ;
329
+ this . setState ( { multiFinalValue : item } ) ;
345
330
// this.toggleExpandableModal(false);
346
331
this . pickerExpandable . current ?. closeExpandable ?. ( ) ;
347
332
this . props . onChange ?. ( item ) ;
@@ -366,15 +351,16 @@ class Picker extends Component {
366
351
367
352
renderCustomModal = ( { visible, toggleExpandable} ) => {
368
353
const { renderCustomModal, children} = this . props ;
369
- const { value } = this . state ;
354
+ const { multiDraftValue } = this . state ;
370
355
371
356
if ( renderCustomModal ) {
372
357
const modalProps = {
373
358
visible,
374
359
toggleModal : toggleExpandable ,
375
360
onSearchChange : this . onSearchChange ,
376
361
children,
377
- onDone : ( ) => this . onDoneSelecting ( value ) ,
362
+ // onDone is relevant to multi mode only
363
+ onDone : ( ) => this . onDoneSelecting ( multiDraftValue ) ,
378
364
onCancel : this . cancelSelect
379
365
} ;
380
366
@@ -399,15 +385,15 @@ class Picker extends Component {
399
385
testID,
400
386
pickerModalProps
401
387
} = this . props ;
402
- const { showExpandableModal, selectedItemPosition, value } = this . state ;
388
+ const { showExpandableModal, selectedItemPosition, multiDraftValue } = this . state ;
403
389
404
390
// if (renderCustomModal) {
405
391
// const modalProps = {
406
392
// visible: showExpandableModal,
407
393
// toggleModal: this.toggleExpandableModal,
408
394
// onSearchChange: this.onSearchChange,
409
395
// children,
410
- // onDone: () => this.onDoneSelecting(value ),
396
+ // onDone: () => this.onDoneSelecting(multiDraftValue ),
411
397
// onCancel: this.cancelSelect
412
398
// };
413
399
@@ -430,7 +416,7 @@ class Picker extends Component {
430
416
topBarProps = { {
431
417
...topBarProps ,
432
418
onCancel : this . cancelSelect ,
433
- onDone : mode === Picker . modes . MULTI ? ( ) => this . onDoneSelecting ( value ) : undefined
419
+ onDone : mode === Picker . modes . MULTI ? ( ) => this . onDoneSelecting ( multiDraftValue ) : undefined
434
420
} }
435
421
showSearch = { showSearch }
436
422
searchStyle = { searchStyle }
@@ -460,16 +446,16 @@ class Picker extends Component {
460
446
modifiers,
461
447
enableModalBlur,
462
448
topBarProps,
463
- pickerModalProps
449
+ pickerModalProps,
450
+ value
464
451
} = this . props ;
465
- const { value} = this . state ;
466
452
467
453
if ( useNativePicker ) {
468
454
return < NativePicker { ...this . props } /> ;
469
455
}
470
456
471
457
// if (_.isFunction(renderPicker)) {
472
- // const {value} = this.state ;
458
+ // const {value} = this.props ;
473
459
474
460
// return (
475
461
// <PickerContext.Provider value={this.getContextValue()}>
@@ -517,7 +503,7 @@ class Picker extends Component {
517
503
importantForAccessibility = { 'no-hide-descendants' }
518
504
value = { label }
519
505
selection = { Constants . isAndroid ? { start : 0 } : undefined }
520
- // Disable TextField expandable feature
506
+ // Disable TextField expandable feature
521
507
expandable = { false }
522
508
renderExpandable = { _ . noop }
523
509
onToggleExpandableModal = { _ . noop }
0 commit comments