react-native-dropdown-picker
react-native-dropdown-picker copied to clipboard
Weird value changes when selecting multiple items.
Hard to describe in words, but here's a video:
https://github.com/hossein-zare/react-native-dropdown-picker/assets/6284016/60b00e7d-d99d-4083-9776-69a372177360
Looks like something is wrong with how the value state is being updated. I kept the video short, but the more I select the wilder it gets.
Minimum reproducible example is here: https://github.com/mersiades/rn-dropdown-picker-mre
export default function TabOneScreen() {
const defaultItems = [
{ label: 'Australia', value: 'au' },
{ label: 'Indonesia', value: 'id' },
{ label: 'New Zealand', value: 'nz' },
];
const [open, setOpen] = useState(false);
const [value, setValue] = useState<string[]>([]);
const [items, setItems] = useState(defaultItems);
return (
<View style={styles.container}>
<DropDownPicker
schema={{
label: 'label',
value: 'value',
}}
mode="BADGE"
listMode={'MODAL'}
value={value}
items={items}
setItems={setItems}
open={open}
setOpen={setOpen}
setValue={(cb) => {
const newValue = cb(value);
setValue(newValue);
}}
multiple
searchable
/>
</View>
);
}
I'm a bit surprised that no one else has raised this issue, which makes me suspect it's me that's doing something wrong, but if so, I've got no idea what it is.
I've run into this issue as well. When logging, I've found that it is because the state transition is not working correctly. For example:
value -> newValue [1, 2] -> [1] // remove 2 [1, 2] -> [2] // remove 1, but the state was not updated correctly from the previous action, resulting in [2]
Expected final state is an empty array, but since the state is not updated the final state looks detached from the actions taken to get there, therefore the "weird" value changes. This is how I've solved it in my code, using a RHF controller.
<Controller name={name} control={control} defaultValue={value} render={({ field: { onChange: internalOnChange, value } }) => ( <DropDownPicker searchable multiple={multiple} open={open} value={value} items={options} setOpen={setOpen} setValue={callback => { const newValue = callback(value); console.log('value', value, 'newValue', newValue); }} onSelectItem={val => { internalOnChange(val.map((v: ItemType<any>) => v.value)); }} /> )} />
Note that setValue doesn't do anything but log currently.
@HugPet @mersiades Can you assign this issue to me.
I have also experienced same issue in multiple select
Can you assign this issue to me.
I don't think I have authority to do that.
Try to use like this setValue={setValue}
, it works fine
Try to use like this
setValue={setValue}
, it works fine
Yes, well, I'm sure there's a reason why all the commenters on this issue are not doing that already.
In my case, setValue={setValue}
will pass a function into my form validation, which causes the validation to fail because it's expecting an array of strings. Hence, I have to use the cb()
to extract the actual field value first.