react-select: Selected value not showing in the input field [Controlled component, single select]

Selected value does not show in the input field for a controlled react-select component with single select.

Version: 2.0.0-beta.6 Demo: https://codesandbox.io/s/ypwq481j7z

import React, { Component} from "react";
import Select from "react-select";

type State = {
  selectedValue: string
};

export default class SingleSelect extends Component<*, State> {
  state = {
    selectedValue: ""
  };

  optionChanged = value => {
    console.log(value);
    this.setState({ selectedValue: value});
  };
  render() {
    console.log(this.state.selectedValue);
    return (
      <div>
        <Select
          options={["abcd", "def", "ghi"]}
          value={this.state.selectedValue}
          onChange={this.optionChanged}
          getOptionLabel={option => option}
          getOptionValue={option => option}
        />
      </div>
    );
  }
}
```

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 18
  • Comments: 31

Most upvoted comments

the solution:

               <Select
                    styles={selectStyles}
                    value={{label : this.state.string}}
                    onChange={(e) => this.handleChange(e)}
                    options={this.state.options}
                />

same problem.

I feel like this is still an issue.

At the moment – to my understanding – if you want to make a controlled Select component you’re required to feed it with value={[{ value, label }]} instead of value={value} like in v1. This seems completely unnecessary.

Having to include label in value is particularly annoying with AsyncSelect where the options aren’t directly available.

For now I’m going back to v1.

Guys, I found a workaround how to avoid it. First of all, you should save your value in state not in string type, but in array type, even if you don’t use multi-select!

state = {
    changeInPercentage: []
}

handleOnchange = (name: string, optionSelected: {label: string, value: string}) => {
this.setState({
      changeInPercentage: [
        {
          label: optionSelected.label,
          value: value
        }
      ]
    }, () => {
      console.log(this.state);
    })
}

<SelectR
styles={customStyles}
isClearable
options={data.changeInPercentage}
onChange={this.handleSelectChangeWithInput.bind(this, 'changeInPercentage')}
value={this.state.changeInPercentage}
/>

It happens, because in the source-code of Select v2 there is a functions, that pass only array-typed values:

export const cleanValue = (value: ValueType): OptionsType => { if (Array.isArray(value)) return value.filter(Boolean); if (typeof value === 'object' && value !== null) return [value]; return []; };

Hi,

you can also do this:

value={{label: this.state.selectedValue, value: this.state.selectedValue} }

Thank you!

The options property in react-select v2 expects the shape Array<Object> where you must define a value and label or provide an arbitrary Option shape with the complimentary functions:

  • getOptionLabel
  • getOptionValue

More info and docs http://bit.ly/react-select-v2

@27percent if you need simple value, consider using a helper function:

const valueFromId = (opts, id) => opts.find(o => o.value === id);

<Select value={valueFromId(this.props.options, this.props.id) />

I think this behavior is very common among other dropdown/selection packages and makes a lot of sense.

If a string is all you are selecting, then your value should be the string AND the label should be the string, as askflow1111 mentions.

Without this as the default behavior, the package wouldn’t be very useful.

Selected value does not show in the input field for a controlled react-select component with single select.

Version: 2.0.0-beta.6 Demo: https://codesandbox.io/s/ypwq481j7z

import React, { Component} from "react";
import Select from "react-select";

type State = {
  selectedValue: string
};

export default class SingleSelect extends Component<*, State> {
  state = {
    selectedValue: ""
  };

  optionChanged = value => {
    console.log(value);
    this.setState({ selectedValue: value});
  };
  render() {
    console.log(this.state.selectedValue);
    return (
      <div>
        <Select
          options={["abcd", "def", "ghi"]}
          value={this.state.selectedValue}
          onChange={this.optionChanged}
          getOptionLabel={option => option}
          getOptionValue={option => option}
        />
      </div>
    );
  }
}

I Solved this in an easy way: you must update the placeholder and update it with your selected option “label” like this:

state = { selectedValue: ’ ’ selectedValuePlaceholder: “select” };

And;

<Select options={[“abcd”, “def”, “ghi”]} getOptionLabel={option => option} getOptionValue={option => option} placeholder={this.state.selectedValuePlaceholder} onChange={({value, label}) => this.setState({selectedValue: value, selectedValuePlaceholder : label})} />

The same problem.

I’ve just run in to the same problem after upgrading from v1. I think the new behaviour is very counterintuitive, especially as this is not obvious in the docs or even the migration guide.

Omg… just stumbled over this issue and I thought react-select was bugged… wtf… This is really not intuitive 😕

Yeah, I’m having the exact same issue. I’ve even tried using one of the code examples from the docs but not even those are working.

EDIT: I changed from react-select to react-virtualized-select on my project and it’s working as expected.

@jossmac that seems really counter-intuitive for a select menu, supplying a value that gets matched with one of the values in the options array to get the label seems like a more natural API. You could potentially support both though - if the value is of shape Array<Object> then use the existing API, if its a simple string, try to match it with one of the options. I’d be happy to do the work and put in a PR if the suggestion sounds sensible to you 😃

Still incredibly strange that the getOptionLabel function wouldn’t apply to displaying the selected values, but it would seem that the surefire hack is to do value={[value]}. I suppose it could be worse, but I feel bad for the droves of people who will still have to waste their time googling for this solution until it’s addressed more properly.

I am running into the same issue with v.2.1.2. At the moment I have as basic a setup as you can imagine:

<Select               options={colors.toArray()}
                            getOptionLabel={option => option}
                            getOptionValue={option => option}
                            value={this.props.color} />

In this snippet colors is a TypeScript List<string>; hence the toArray() call.

So is the conclusion from this thread that I need to convert the string[] into Option[] with label/value shape for things to work? If so, that isn’t the worst thing ever, but I agree with those who feel it is a bit cumbersome for such a basic scenario.

Just seeking clarification.