Skip to content

Commit adeb3f3

Browse files
authored
fix picker multi value (#1649)
* fix picker multi value * Revert "Merge branch 'master' into fix/picker_multiValue" This reverts commit b9f020e, reversing changes made to 834d846. * Revert "Revert "Merge branch 'master' into fix/picker_multiValue"" This reverts commit 8dc646f. * Fix merge issues and add comment
1 parent a488b24 commit adeb3f3

File tree

1 file changed

+29
-43
lines changed

1 file changed

+29
-43
lines changed

src/components/picker/index.js

Lines changed: 29 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// TODO: deprecate all places where we check if _.isPlainObject
22
// TODO: deprecate getItemValue prop
33
// TODO: deprecate getItemLabel prop
4+
// TODO: Add initialValue prop
45
// TODO: consider deprecating renderCustomModal prop
56
// TODO: deprecate onShow cause it's already supported by passing it in pickerModalProps
67
import _ from 'lodash';
@@ -168,10 +169,10 @@ class Picker extends Component {
168169
super(props);
169170

170171
this.state = {
171-
value: props.value,
172-
prevValue: undefined,
173172
selectedItemPosition: 0,
174-
items: Picker.extractPickerItems(props)
173+
items: Picker.extractPickerItems(props),
174+
multiDraftValue: props.value,
175+
multiFinalValue: props.value
175176
};
176177

177178
if (props.mode === Picker.modes.SINGLE && Array.isArray(props.value)) {
@@ -192,26 +193,10 @@ class Picker extends Component {
192193
}
193194

194195
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+
}
215200
}
216201
return null;
217202
}
@@ -236,12 +221,12 @@ class Picker extends Component {
236221
}
237222

238223
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;
241226
const pickerValue = !migrate && _.isPlainObject(value) ? value?.value : value;
242227
return {
243228
migrate,
244-
value: pickerValue,
229+
value: mode === Picker.modes.MULTI ? multiDraftValue : pickerValue,
245230
onPress: mode === Picker.modes.MULTI ? this.toggleItemSelection : this.onDoneSelecting,
246231
isMultiMode: mode === Picker.modes.MULTI,
247232
getItemValue,
@@ -320,28 +305,28 @@ class Picker extends Component {
320305
// };
321306

322307
toggleItemSelection = item => {
323-
const {getItemValue} = this.props;
324-
const {value} = this.state;
308+
const {getItemValue, migrate} = this.props;
309+
const {multiDraftValue} = this.state;
325310
let newValue;
326-
if (_.isPlainObject(value)) {
327-
newValue = _.xorBy(value, [item], getItemValue || 'value');
311+
if (!migrate) {
312+
newValue = _.xorBy(multiDraftValue, [item], getItemValue || 'value');
328313
} else {
329-
newValue = _.xor(value, [item]);
314+
newValue = _.xor(multiDraftValue, [item]);
330315
}
331316

332-
this.setState({value: newValue});
317+
this.setState({multiDraftValue: newValue});
333318
};
334319

335320
cancelSelect = () => {
336-
this.setState({value: this.props.value});
321+
this.setState({multiDraftValue: this.state.multiFinalValue});
337322
// this.toggleExpandableModal(false);
338323
this.pickerExpandable.current?.closeExpandable?.();
339324
this.props.topBarProps?.onCancel?.();
340325
};
341326

342327
onDoneSelecting = item => {
343328
this.clearSearchField();
344-
this.setState({value: item});
329+
this.setState({multiFinalValue: item});
345330
// this.toggleExpandableModal(false);
346331
this.pickerExpandable.current?.closeExpandable?.();
347332
this.props.onChange?.(item);
@@ -366,15 +351,16 @@ class Picker extends Component {
366351

367352
renderCustomModal = ({visible, toggleExpandable}) => {
368353
const {renderCustomModal, children} = this.props;
369-
const {value} = this.state;
354+
const {multiDraftValue} = this.state;
370355

371356
if (renderCustomModal) {
372357
const modalProps = {
373358
visible,
374359
toggleModal: toggleExpandable,
375360
onSearchChange: this.onSearchChange,
376361
children,
377-
onDone: () => this.onDoneSelecting(value),
362+
// onDone is relevant to multi mode only
363+
onDone: () => this.onDoneSelecting(multiDraftValue),
378364
onCancel: this.cancelSelect
379365
};
380366

@@ -399,15 +385,15 @@ class Picker extends Component {
399385
testID,
400386
pickerModalProps
401387
} = this.props;
402-
const {showExpandableModal, selectedItemPosition, value} = this.state;
388+
const {showExpandableModal, selectedItemPosition, multiDraftValue} = this.state;
403389

404390
// if (renderCustomModal) {
405391
// const modalProps = {
406392
// visible: showExpandableModal,
407393
// toggleModal: this.toggleExpandableModal,
408394
// onSearchChange: this.onSearchChange,
409395
// children,
410-
// onDone: () => this.onDoneSelecting(value),
396+
// onDone: () => this.onDoneSelecting(multiDraftValue),
411397
// onCancel: this.cancelSelect
412398
// };
413399

@@ -430,7 +416,7 @@ class Picker extends Component {
430416
topBarProps={{
431417
...topBarProps,
432418
onCancel: this.cancelSelect,
433-
onDone: mode === Picker.modes.MULTI ? () => this.onDoneSelecting(value) : undefined
419+
onDone: mode === Picker.modes.MULTI ? () => this.onDoneSelecting(multiDraftValue) : undefined
434420
}}
435421
showSearch={showSearch}
436422
searchStyle={searchStyle}
@@ -460,16 +446,16 @@ class Picker extends Component {
460446
modifiers,
461447
enableModalBlur,
462448
topBarProps,
463-
pickerModalProps
449+
pickerModalProps,
450+
value
464451
} = this.props;
465-
const {value} = this.state;
466452

467453
if (useNativePicker) {
468454
return <NativePicker {...this.props}/>;
469455
}
470456

471457
// if (_.isFunction(renderPicker)) {
472-
// const {value} = this.state;
458+
// const {value} = this.props;
473459

474460
// return (
475461
// <PickerContext.Provider value={this.getContextValue()}>
@@ -517,7 +503,7 @@ class Picker extends Component {
517503
importantForAccessibility={'no-hide-descendants'}
518504
value={label}
519505
selection={Constants.isAndroid ? {start: 0} : undefined}
520-
// Disable TextField expandable feature
506+
// Disable TextField expandable feature
521507
expandable={false}
522508
renderExpandable={_.noop}
523509
onToggleExpandableModal={_.noop}

0 commit comments

Comments
 (0)