React-select: Can't give only the value in props, it's only working with full object option

Created on 24 Sep 2018  路  16Comments  路  Source: JedWatson/react-select

For these options:

const options = [{ value: 1, label: "one" }, { value: 2, label: "Two" }]

In React Select v1.x.x, you could do this to select the first option:

<Select
  value={1}
  options={options}
/>

Now in React Select v2, you have to do this:

<Select
  value={{ value: 1, label: "one" }}
  options={options}
/>

I guess it's a bug since it's not documented anywhere (not mentionned in Upgrade Guide).

Non-working example:
https://codesandbox.io/s/l946w963r7

issubug-unconfirmed issureviewed

Most helpful comment

Taking away the simple value as the default functionality was a bad decision.

I think someone needs to fork this library and put it back the way it was. Anyone willing to help with this?

All 16 comments

Same issue here.

Adding isOptionSelected renderes the selected value
screen shot 2018-09-24 at 11 05 47

isOptionSelected={(option, values) => {
        return values.includes(option.value);
}}

Ignore this.

I ended up going this route:

Props with full object options, and value is an array of values;

props = {
    options = [{value: x, label: y}, ...];
    value: [x, ...]
}

getValue returns the proper {value: x, label: y} objects for values;

const getValue = (opts, val) => {
  return opts.filter(o => val.includes(o.value));
};

renderable

  return (
    <Select
      options={props.options}
      onChange={props.onChange}
      isMulti
      isDisabled={props.disabled}
      placeholder={label}
      value={getValue(props.options, props.value)}
      style={{ width: '80%', margin: '30px 0' }}
    />
  );

We did something similar for the moment.
It would be nice to know if it's a regression and will be solved.

Nice workaround, @dreallday . Works for my implementation with React Table:
```
const options = [
{ value: 'USD', label: 'USD' },
{ value: 'GBP', label: 'GBP' },
{ value: 'AUD', label: 'AUD' },
];

ReactTable.columns = [
...,
{
Header: 'Currency',
accessor: 'currency',
Cell: (row) => {
const value = this.state.data[row.index][row.column.id];
const getValue = (opts, val) => opts.filter(o => val.includes(o.value));

    return (
        <div>
            <Select value={getValue(options, value)}
                onChange={selectedOption => this.onChangeCurrency(row, selectedOption ? selectedOption.label : 'USD')}
                options={options}
            />
        </div>
    );
},
 width: 150,

},
...
];

this seems like a pretty significant regression... it's kind of a main feature of a select library

i'd happily submit a PR if i could figure out where the value is being set

I think this is the intended behaviour in v2, there's a brief mention of it here

React-select v1 allowed to use strings for the value prop, but with v2 it uses arrays or objects in all the cases. If you still want to use strings you can easily do so by filtering the value out off all your options:

aha, interesting. my issue is that i'm wrapping the Select component at least once, if not multiple times... so I don't have access all the way down the chain to the options that were passed in, and can't filter against them...

now i have to re-implement this in a global wrapper for this library, which seems silly since not only is it a deviation from the behavior of the HTML component it is replacing but also this seems like a very common use-case

seems like an oversight that made it's way into the docs as an afterthought 馃槩

Taking away the simple value as the default functionality was a bad decision.

I think someone needs to fork this library and put it back the way it was. Anyone willing to help with this?

I'm pretty surprised this isn't highlighted somewhere as a breaking change between v1 and v2. At least have a section in the upgrade guide labeled "breaking changes".

Any ideas why this change was made? New way using an object as value is not a standard UI components...

Same kind of problem here with AsyncSelect
My main object returns me the id of the linked object and I can't display value only according to simple id which is enough for record to be display according to options....

I'll have to also fetch my linked object store to have full value that is a shame...

So I'm supporting the new model for setting value (rather than passing in a string) and it works fine for Select but doesn't work with AsyncSelect. WTF?

BTW, add my voice to the people pretty frustrated at finding this breaking change from v1 to v2, especially when it breaks a central behavior of the HTML component it replaces. I can't understand the reasoning either - how hard is it to preserve this backwards-compatible behavior?

Since I dont see any further activity; is it correct to assume, this would remain the same ?

It appears so. There's quite a few people asking about this as well on this thread. Guess that's the way it has to be.

Really annoying considering using this with Formik now requires 5x the amount of code vs the way it used to be in v1. Requiring everyone to translate from object form to single value form for posting is also very annoying. I'm not sure why the default can't be value based, with the ability to specify a parameter that toggles value/object storage. Super frustrating having to go through 80 forms and add bloat to everything for basic behavior.

So I found that you can at least post the simple value rather than the whole object, but this doesn't change setting the value so it's still quite a pain.

<Select simpleValue={true} />

Greetings,

The upgrade guide in the documentation does state that this functionality has been changed as already mentioned above.

React-select v1 allowed to use strings for the value prop, but with v2 it uses arrays or objects in all the cases. If you still want to use strings you can easily do so by filtering the value out off all your options:

This would disqualify this behavior as being a bug as it is documented.

In regards to a feature request, I would argue that this is something that could be accomplished fairly quickly with hooks for state and effect.

Here is a working codesandbox

const MySelect = ({ simpleValue, options, ...props }) => {
  const [value, setValue] = useState(props.value);

  useEffect(function getSelectedOption() {
    if (simpleValue !== undefined && options.length) {
      const val = Array.isArray(simpleValue)
        ? options.filter((x) => simpleValue.includes(x.value))
        : options.find((x) => x.value === simpleValue);
      setValue(val);
   }}, [ simpleValue, options ] );

  const onChange = (option) => {
    setValue(option);
    props.onChange && props.onChange(option);
  };

  return (
    <Select {...props} options={options} onChange={onChange} value={value} />
  );
};

You can then call it by passing in a simpleValue prop and it works for both single select and isMulti.

  const options = [
    { label: "Option 1", value: 1 },
    { label: "Option 2", value: 2 },
    { label: "Option 3", value: 3 }
  ];

  const simpleValue = 2;
  const simpleMultiValue = [1, 2];

  return (
    <>
      <MySelect options={options} simpleValue={simpleValue} />
      <MySelect isMulti options={options} simpleValue={simpleMultiValue} />
    </>
);

While I do not argue that this likely is very much a pain for users who were using simpleValue for version 1 and I would even go so far as to call the naming itself confusing (I need the value of value?).

That said, there is growing complexity already in the application and supporting simpleValue would likely add more pain points to the different internal methods as comparing the selected "value" becomes more ambiguous. In my humble opinion, the goal here should be to allow developers the tools to easily build the functionality that they need as opposed to trying to provide everything for everyone and bloating bundle sizes in the process.

The above seems like a perfect example of having the tools to build the Select component the way a dev wants using only one state hook, one effect hook, and a curried onChange handler. While I don't discount the impact, breaking changes, and potentially hard to find breaking changes in the documentation, I think that this could potentially be better discussed in the Discussions area. We can certainly reopen this issue should the discussion prove that it would be of positive cost/benefit to re-support it as a feature, but as things are, it does not appear to be the case.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MindRave picture MindRave  路  3Comments

ericj17 picture ericj17  路  3Comments

sampatbadhe picture sampatbadhe  路  3Comments

coder-guy22296 picture coder-guy22296  路  3Comments

pgoldweic picture pgoldweic  路  3Comments