hossein-zare / react-native-dropdown-picker

A single / multiple, categorizable, customizable, localizable and searchable item picker (drop-down) component for react native which supports both Android & iOS.
https://hossein-zare.github.io/react-native-dropdown-picker-website/
MIT License
969 stars 294 forks source link

Weird value changes when selecting multiple items. #737

Open mersiades opened 5 months ago

mersiades commented 5 months ago

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.

HugPet commented 4 months ago

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.

PradeepThite commented 3 months ago

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

PradeepThite commented 3 months ago

I have also experienced same issue in multiple select

mersiades commented 2 months ago

Can you assign this issue to me.

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