16

I am working on react-select library and facing some issues, I am using redux-form library and importing <Field /> component from it. So that I can submit the values via form to service.

Below mentioned code works fine, when I use default <Select> from react-select. I can able to select the values from the drop down and the value will be selected even on focus out the value will remain. But selected value is not submitting via form due to redux-form that's why I am wrapping <Select /> component and using with <Field name="sample" component={RenderSelectInput} id="sampleEX" options={options} />

import React from 'react';
import Select from 'react-select';
import RenderSelectInput from './RenderSelectInput'; // my customize select box

var options = [{ value: 'one', label: 'One' }, { value: 'two', label: 'Two' }];


class SelectEx extends React.Component {
    constructor() {
        super();
        this.state = { selectValue: 'sample' }
        this.updateValue = this.updateValue.bind(this);
    }

    updateValue(newValue) {
        this.setState({ selectValue: newValue })
    }

    render() {

        return (
            <div>
                <Select name="select1" id="selectBox" value={this.state.selectValue} options={options} onChange={this.updateValue}/>

                //This works but value won't submit ...

                <Field name="sample" component={RenderSelectInput} id="sampleEX" options={options} />
            //For this, selected value vanishes once I come out of component. 
            </div>
        )
    }
}

export default SelectEx;

But when I use with my customized select (I am wrapping the to submit the value from form) the <Select> component can be visible in UI even the values also. But unable to select the value from dropdown ..., If I select also it displays in the <Select> box but on focus out it vanishes. Please help me ...

RenderSelectInput component:

import React from 'react';
import {Field, reduxForm} from 'redux-form';
import Select from 'react-select';
import 'react-select/dist/react-select.css';


const RenderSelectInput = ({input, options, name, id}) => (

    <div>
        <Select {...input} name={name} options={options} id={id} />
    </div>
)

export default RenderSelectInput;
0

5 Answers 5

11

When using react-select with redux-form, you'll need to change the default behavior of onChange and onBlur method and call redux-form's onChange and onBlur method respectively.

So, Try this:

const RenderSelectInput = ({input, options, name, id}) => (
    <Select 
         {...input}
         id={id} 
         name={name} 
         options={options}
         value={input.value}
         onChange={(value) => input.onChange(value)}
         onBlur={(value) => input.onBlur(value)}
    />
)

and use the above component like

<Field component={RenderSelectInput} />

Calling redux-form's onBlur method when focus is removed from the Select field will prevent loss of value.

Sign up to request clarification or add additional context in comments.

9 Comments

Hi, The above mentioned solution did not resolve my problem, I am seeing same behavior. I can able to select values from dropdown list but the value vanishes when I click outside. You have mentioned onChange in RenderSelectInput component but not in <Field /> is this causing issue ? or 'value' is not mentioned in either RenderSelectInput or Field component ..
Which version of react-select are you using?
Have you specified onBlur function, as I said in the answer?
I am using New version 1.0.0-rc which is available now in GitHub.com.
probably a little late, but I am facing now the same problem and solved it calling input.onBlur without arguments: onBlur={() => input.onBlur()}. Apparently, the onBlur method of Select receives an event and input.value is an empty string and calling input.onBlur with any of those values dispatches the BLUR action with payload = '' which empties the value of the field in the redux state
|
3

Here this worked for me,

import React, { Component } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';

export default class RenderSelectInput extends Component {
 onChange(event) {
  if (this.props.input.onChange && event != null) {
   this.props.input.onChange(event.value);
  } else {
   this.props.input.onChange(null);
  }
 }

 render() {
  const { input, options, name, id, ...custom } = this.props;
  return (
   <Select
    {...input}
    {...custom}
    id={id}
    name={name}
    options={options}
    value={this.props.input.value || ''}
    onBlur={() => this.props.input.onBlur(this.props.input.value)}
    onChange={this.onChange.bind(this)}
   />
  );
 }
}

this was extracted from here: https://ashiknesin.com/blog/use-react-select-within-redux-form/

1 Comment

Thanks, that worked for me. Just a minor change to support multi={true}. In onChange use: if (event.value) { this.props.input.onChange(event.value); } else { this.props.input.onChange(event); }
2

Use this which works perfectly and it also handles redux form validation.

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


class CustomSelect extends Component {

 render() {
   const {meta: {touched, error}} = this.props;
   const className = ` form-group mb-3 ${touched && error ? 'has-danger' : '' }`;
   return (    
        <FormGroup>
                <Select
                      {...this.props}
                       value={this.props.input.value}
                       onChange={(value) => this.props.input.onChange(value)}
                       onBlur={() => this.props.input.onBlur(this.props.input.value)}
                       options={this.props.options}
                       placeholder={this.props.placeholder}
                    />
                    <div className={className}>
                         <div className="text-help">
                              {touched ? error : ''}
                          </div>
                     </div>
           </FormGroup>

            );

Use the CustomSelect component in redux form field component as

   <Field
        name='country_name'
        options={this.state.countries}
        component={CustomSelect}
        placeholder="Select your country"
   />

Comments

2

I had to call the onBlur without any argument. The issue with Hardik's answer was, it was not working in iPad (May be also in other iOS or touch devices. I was unable to check).

The onBlur event is automatically triggered along with the onChange event in iPad. It caused the select value to reset to its initial value. So I had to call onBlur method like this,

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

const RenderSelectInput = ({input, options, name, id}) => (
    <Select 
         {...input}
         id={id} 
         name={name} 
         options={options}
         value={input.value}
         onChange={(value) => input.onChange(value)}
         onBlur={(value) => input.onBlur()}
    />
)

and used as,

<Field component={RenderSelectInput} />

Comments

1

Try setting onBlurResetInput property to false.

Something like.

const SelectInput = ({input: { onChange, value }, options, name, id}) => (
    <Select              
      name={name}
      value={value} 
      options={options}
      onChange={onChange}
      onBlurResetsInput={false}
    />
)

Hope this helps!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.