JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.63k stars 4.13k forks source link

[Multi select] onChange returns null when no values instead of [] #3632

Closed nicolasletoublon closed 3 years ago

nicolasletoublon commented 5 years ago

All is in the title. We implemented a version of the Multi select. and it seems that when you clear the last value (or the only one) of the field, the onChange returns you null. I would clearly expect an empty array at this stage :)

Here is your sandbox updated with the onChange callback :) https://5jtqt.codesandbox.io/

Thanks for looking at it!

ragesoss commented 5 years ago

This appears to be the intended behavor with v3: https://github.com/JedWatson/react-select/pull/3416

I just ran into a bug in my app because of this change as well. Curious as to how others handle it.

speir-wang commented 5 years ago

And interestingly, if user uses the clear all button to remove all the values in Multi select, the value would be set to an empty array.

I was wondering why removing the last value results in null but clicking clear all button results in []? Shouldn't they be treated in the same manner?

someden commented 5 years ago

Simple example:

import React from 'react';
import Select from 'react-select';

export default () => (
  <Select
    isMulti
    options={[{ value: 'ocean', label: 'Ocean' }, { value: 'blue', label: 'Blue' }]}
    onChange={console.log}
  />
);

ScreenRecording2019-06-18at1

someden commented 5 years ago

Temporary workaround for this bug:

import React, { Component } from 'react';
import ReactSelect from 'react-select';

class Select extends Component {
  defaultProps = {
    onChange: () => {},
  };

  handleChange = selected =>
    this.props.onChange(!selected && this.props.isMulti ? [] : selected);

  render() {
    return <ReactSelect {...this.props} onChange={this.handleChange} />;
  }
};

export default Select;
stearruda commented 5 years ago

I was having some problems with that as well and to fix it I've redefined the value on the onChange to an empty array.

const MultiSelect = () => {
  const handleOnChange = value => {
    if (value === null) {
      value = [];
    }
  };

  return (
    <Select
      isSearchable
      isMulti
      onChange={handleOnChange}
    />
  );
}

export default MultiSelect;
TravnikovDev commented 5 years ago

I am still having the same Issue

luksari commented 4 years ago

I was having the very same problem, needed to use onChange from redux-form in my component so, this is workaround for redux-form and typescript

const handleOnChange = (value: ValueType<SelectableItem>, action: ActionMeta) => {
   if (!onChange) return;
   if (value === null) {
     onChange([], action);
   } else {
     onChange(value, action);
   }
 };
<ReactSelect
     onChange={handleOnChange} ... />
danielimmke commented 4 years ago

Super simple inline fix for people Googling:

onChange={(value) => stateChangeMethod(value || [])}

Replace stateChangeMethod with whatever you're using to update state. In my case I was using Hooks so I had a specific function just for that bit of state.

bladey commented 4 years ago

Hello -

In an effort to sustain the react-select project going forward, we're closing old issues.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

rusakovic commented 4 years ago

@bladey Hello.

Thank you. But issue is still here. If you remove value from input dropdown field by pressing backspace, returned value will be null but not [] react-select 3.1.0

akhilaudable commented 4 years ago

+1

bladey commented 4 years ago

Thanks @rusakovic!

kirkobyte commented 4 years ago

Would the maintainers be happy with a PR that normalises empty values for isMulti fields to [] for initial empty values & after clearing the field? Then we could keep the normalisation #3416 intended, while also having a more useful empty state

Methuselah96 commented 4 years ago

I'm definitely in favor of this. I'm working on porting react-select to TypeScript and it there a lot of places that return [] when there are no options selected and only couple of places where we actually remember to change it to null.

@bladey @JedWatson I can make a PR for this change if you guys are okay with this change. There are only a couple of places where we would need to change the behavior in order for it to be consistent.

darrendahl commented 4 years ago

+1, causing some issues on my end, Basically the issue is that the isClearable "X" returns [] but removing all tags returns null

--- I know we can fix by making a wrapper and normalize to either null or [], but ideally would return same thing, since its a very similar action

ejose19 commented 4 years ago

I also agree the discrepancy between container "X" and element "X" is not expected, and empty multi select should be [] not null, to avoid any extra conversion by users.

I'm using (value ?? []) in the meanwhile.