React-select: When component is searchable, onBlur always resets value even when onBlurResetsInput is set to false

Created on 1 Mar 2016  路  10Comments  路  Source: JedWatson/react-select

Hi.
These are the options I'm using:

        <Select
          {...field}
          value={field.value}
          name={field.name}
          searchable
          onBlurResetsInput={false}
          clearable={false}
          className={"form-control"}
          options={options}
        />

Though I've tried all sorts of combinations, and the only way I can get selected value to stick is to set searchable to false. Otherwise, input resets when I click outside select.
Watching the state change, selecting option really does set value, and onBlur resets it.

Bug, or am I doing something wrong?

Most helpful comment

As a workaround, you can add onBlur={() => {}} or if you're using redux-form onBlur={() => field.onBlur({value: field.value})}

All 10 comments

I have seen this as well.

So I'm not crazy. Its quite a bug. Found any solution around it?

As a workaround, you can add onBlur={() => {}} or if you're using redux-form onBlur={() => field.onBlur({value: field.value})}

Seems like this is still an issue.

@tiagoengel's suggestion is a decent workaround. If you're using redux-form v6, you'll want to use the updated blur handler as follows (make sure you place it after you spread the redux-form input prop!)

onBlur={() => input.onBlur(input.value)}

Link to doc for onBlur() signature.

it seems that input.value match the value/ label pair :

My store state when selecting an item :

image

So, it works better if onBlur was used with input.value.value :

onBlur={() => input.onBlur(input.value.value)}

@M3lkior

Edit: You're right! Just realized I'm overriding onChange as well and only passing react-select's newValue.value to redux form. I think that's the way to go. It allows redux-form to only ever have a simple string value on each change, and it makes the onBlur method I wrote above just work.

So for redux-form users, fixing this issue _properly_ involves both custom onChange and onBlur handlers. I'm using the following code which handles single values, multi-select arrays, and other edge cases.

handleChange(newValue) {
  // Workaround for single-select mode where manually deleting value results in an empty array, not `null`
  if (Array.isArray(newValue) && !newValue.length) {
    newValue = null;
  }

  // Oddly, the entire { value, label } object is provided as a new value (or array of them)
  // So, we'll manually convert to just values
  if (Array.isArray(newValue)) {
    newValue = newValue.map(obj => obj.value);
  }
  else if (newValue) {
    newValue = newValue.value;
  }

  // Workaround for https://github.com/JedWatson/react-select/issues/1256
  if (this.selectInstance) {
    this.selectInstance.inputValue = '';
  }

  this.props.input.onChange(newValue);
}

// Custom blur handler for bug workarounds
handleBlur() {
  // Workaround for https://github.com/JedWatson/react-select/issues/1256
  if (this.selectInstance) {
    this.selectInstance.inputValue = '';
  }

  // Workaround for https://github.com/JedWatson/react-select/issues/805
  this.props.input.onBlur(this.props.input.value);
}

And wiring it up like so:

<Select
  {...this.props.input}
  onChange={this.handleChange}
  onBlur={this.handleBlur}
/>

It's not working on mobile though...
This is react-select 2.0 by the way.

<Select
            {...props}
            classes={props.classes}
            components={components}
            name={props.input.name}
            value={props.input.value}
            onChange={props.input.onChange}
            onBlur={() => {
                props.input.onBlur(props.input.value);
            }}
            textFieldProps={{
                error: props.meta.touched && Boolean(props.meta.error),
                label: props.meta.touched && props.meta.error,
                InputLabelProps: {
                    shrink: true,
                },
            }}
            isClearable
/>

@alfredoqt I was running into the same issue, it looks like the blur and change actions from redux form were being called simultaneously when on mobile so the props weren't updated when the blur function checks the input.value prop. I just wrote a blur handler to check the value on the next tick and it solved it for me.

const handleBlur = () => {
    setTimeout(() => {
      props.input.onBlur(props.input.value);
    }, 1);
  };

resolved that issue with

handleInputChange = (inputValue, params) => {
  if (params.action === 'input-change') {
    this.setState({inputValue});
  }
};

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!

Was this page helpful?
0 / 5 - 0 ratings