react-native-dropdown-picker icon indicating copy to clipboard operation
react-native-dropdown-picker copied to clipboard

Weird value changes when selecting multiple items.

Open mersiades opened this issue 1 year ago • 6 comments

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.

mersiades avatar Jan 18 '24 07:01 mersiades

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 avatar Feb 22 '24 09:02 HugPet

@HugPet @mersiades Can you assign this issue to me.

PradeepThite avatar Mar 30 '24 08:03 PradeepThite

I have also experienced same issue in multiple select

PradeepThite avatar Mar 30 '24 08:03 PradeepThite

Can you assign this issue to me.

I don't think I have authority to do that.

mersiades avatar Apr 06 '24 07:04 mersiades

Try to use like this setValue={setValue}, it works fine

muneebahmedayub avatar Jul 25 '24 14:07 muneebahmedayub

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.

mersiades avatar Aug 21 '24 08:08 mersiades