Skip to content

Commit 969e143

Browse files
committed
fix picker multi value
1 parent d3db562 commit 969e143

File tree

1 file changed

+23
-38
lines changed

1 file changed

+23
-38
lines changed

src/components/picker/index.js

Lines changed: 23 additions & 38 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
import _ from 'lodash';
56
import PropTypes from 'prop-types';
67
import React, {Component} from 'react';
@@ -162,10 +163,10 @@ class Picker extends Component {
162163
super(props);
163164

164165
this.state = {
165-
value: props.value,
166-
prevValue: undefined,
167166
selectedItemPosition: 0,
168-
items: Picker.extractPickerItems(props)
167+
items: Picker.extractPickerItems(props),
168+
multiDraftValue: props.value,
169+
multiFinalValue: props.value
169170
};
170171

171172
if (props.mode === Picker.modes.SINGLE && Array.isArray(props.value)) {
@@ -186,26 +187,10 @@ class Picker extends Component {
186187
}
187188

188189
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+
}
209194
}
210195
return null;
211196
}
@@ -230,12 +215,12 @@ class Picker extends Component {
230215
}
231216

232217
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;
235220
const pickerValue = !migrate && _.isPlainObject(value) ? value?.value : value;
236221
return {
237222
migrate,
238-
value: pickerValue,
223+
value: mode === Picker.modes.MULTI ? multiDraftValue : pickerValue,
239224
onPress: mode === Picker.modes.MULTI ? this.toggleItemSelection : this.onDoneSelecting,
240225
isMultiMode: mode === Picker.modes.MULTI,
241226
getItemValue,
@@ -314,27 +299,27 @@ class Picker extends Component {
314299
};
315300

316301
toggleItemSelection = item => {
317-
const {getItemValue} = this.props;
318-
const {value} = this.state;
302+
const {getItemValue, migrate} = this.props;
303+
const {multiDraftValue} = this.state;
319304
let newValue;
320-
if (_.isPlainObject(value)) {
321-
newValue = _.xorBy(value, [item], getItemValue || 'value');
305+
if (!migrate) {
306+
newValue = _.xorBy(multiDraftValue, [item], getItemValue || 'value');
322307
} else {
323-
newValue = _.xor(value, [item]);
308+
newValue = _.xor(multiDraftValue, [item]);
324309
}
325310

326-
this.setState({value: newValue});
311+
this.setState({multiDraftValue: newValue});
327312
};
328313

329314
cancelSelect = () => {
330-
this.setState({value: this.props.value});
315+
this.setState({multiDraftValue: this.state.multiFinalValue});
331316
this.toggleExpandableModal(false);
332317
_.invoke(this.props, 'topBarProps.onCancel');
333318
};
334319

335320
onDoneSelecting = item => {
336321
this.clearSearchField();
337-
this.setState({value: item});
322+
this.setState({multiFinalValue: item});
338323
this.toggleExpandableModal(false);
339324
_.invoke(this.props, 'onChange', item);
340325
};
@@ -372,15 +357,15 @@ class Picker extends Component {
372357
testID,
373358
pickerModalProps
374359
} = this.props;
375-
const {showExpandableModal, selectedItemPosition, value} = this.state;
360+
const {showExpandableModal, selectedItemPosition, multiDraftValue} = this.state;
376361

377362
if (renderCustomModal) {
378363
const modalProps = {
379364
visible: showExpandableModal,
380365
toggleModal: this.toggleExpandableModal,
381366
onSearchChange: this.onSearchChange,
382367
children,
383-
onDone: () => this.onDoneSelecting(value),
368+
onDone: () => this.onDoneSelecting(multiDraftValue),
384369
onCancel: this.cancelSelect
385370
};
386371

@@ -403,7 +388,7 @@ class Picker extends Component {
403388
topBarProps={{
404389
...topBarProps,
405390
onCancel: this.cancelSelect,
406-
onDone: mode === Picker.modes.MULTI ? () => this.onDoneSelecting(value) : undefined
391+
onDone: mode === Picker.modes.MULTI ? () => this.onDoneSelecting(multiDraftValue) : undefined
407392
}}
408393
showSearch={showSearch}
409394
searchStyle={searchStyle}
@@ -429,7 +414,7 @@ class Picker extends Component {
429414
}
430415

431416
if (_.isFunction(renderPicker)) {
432-
const {value} = this.state;
417+
const {value} = this.props;
433418

434419
return (
435420
<View left>

0 commit comments

Comments
 (0)