export class ReactSelectWrapper extends React.Component {
constructor(props) {
super(props);
}
render = () => {
return (<Select
{...this.props}
/>);
}
}
export const renderReactSelectWrapper = props => (<ReactSelectWrapper {...props}/>);
var options = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' }
];
<Field name="name" component={renderReactSelectWrapper} options={options}>
There is a major problem, the selected value gets cleared on blur. This can't be prevented by onBlurResetsInput(false). If anyone has any suggestion to avoid this, you're welcome to provide any help.
You're probably not setting the value
prop in your react-select
component. So when Redux updates state, it blows away any selection made.
Your code sample is missing an onChange
handler (not sure if you excluded that on purpose). That onChange
handler should call a Redux action to set state to the selected value. Then use that value to set react-select
's value
prop.
That should do the trick. :)
@gojohnnygo The onChange should be wired up via the spread operator {...props} in @duketwo sample code.
I was also having this problem and when I was trying to debug it I changed my code like this
const MemberSelect = ({users, onChange, value, onBlur}) => {
const usersOptions = users.map(
user => ({
label: user.firstName + " " + user.lastName,
value: user.id
}));
function handleChagne(value) {
onChange(value);
}
function handleBlur() {
onBlur();
}
// https://github.com/JedWatson/react-select/issues/1129
return (
<FormElement name="members" label="Members">
<Select
name="members"
options={usersOptions}
multi
simpleValue
disabled={false}
onChange={handleChagne}
value={value}
onBlur={handleBlur}
onBlurResetsInput={false}/>
</FormElement>
);
};
Having the code like this with handleBlur
calling onBlur
from Redux Forms works for some reason while the code below that directly wires Redux Forms' onBlur
doesn't work.
import React, {PropTypes} from "react";
import FormElement from "../../common/forms/FormElement";
import Select from "react-select";
const MemberSelect = ({users, onChange, value, onBlur}) => {
const usersOptions = users.map(
user => ({
label: user.firstName + " " + user.lastName,
value: user.id
}));
function handleChagne(value) {
onChange(value);
}
// https://github.com/JedWatson/react-select/issues/1129
return (
<FormElement name="members" label="Members">
<Select
name="members"
options={usersOptions}
multi
simpleValue
disabled={false}
onChange={handleChagne}
value={value}
onBlur={onBlur}
onBlurResetsInput={false}/>
</FormElement>
);
};
MemberSelect.propTypes = {
users: PropTypes.array.isRequired,
onChange: PropTypes.func.isRequired,
members: PropTypes.array
};
export default MemberSelect;
On further testing it looks like the proxy that is being pass to onBlur might be causing problems for Redux Forms. The code below causes things to stop working for me.
function handleBlur(proxy) {
onBlur();
}
return (
<FormElement name="members" label="Members">
<Select
name="members"
options={usersOptions}
multi
simpleValue
disabled={false}
onChange={onChange}
value={value}
onBlur={handleBlur}/>
</FormElement>
);
so it seems like it's having that proxy passed along that's causing the problem.
Looks like Redux Form is expecting a synthetic event or the current value. In chrome it looks like a synthetic event coming through so not sure what the problem is.
onBlur(eventOrValue) : Function
A function to call when the form field loses focus. It expects to either receive the React SyntheticEvent or the current value of the field.
I don't know if it's a regression, or just change of behavior but I am noticing the onChange
in react-select is receiving the { label, value }
object, and redux-form expects onChange
to receive value
so I did this:
const selInput = (props) => {
const { children, input, options } = props
function handleInputChange({ value }) {
props.input.onChange(value)
}
return (
<label className={props.className}>
{children}
<Select
clearable={false}
searchable={false}
options={options}
{...input}
onChange={handleInputChange}
/>
</label>
)
}
<Field name="browser" className="browser-dropdown" component={selInput} options={browsers}>
Browser used
</Field>
This didn't seem to be the case pre-rc4
Closing this issue since it seems to have been answered sufficiently already. :smile:
Also, this sort of question is probably better suited to Stack Overflow (or similar) rather than GitHub since it's a request for help and not a bug/feature. :grin:
For me, the following works for [email protected]
and [email protected]
<Select
value={input.value}
onChange={input.onChange}
onBlur={() => input.onBlur(input.value)}
options={optionsToRender}
placeholder={placeholder}
className="form-control"
simpleValue
/>
Thanks @paothegit This works very well!
@paothegit thank you, works well. Here is my Field element.
Somewhere
let options = [{value:1, label: 'select option'}];
And in render
<Field name="name"
component={props =>
<Select
value={props.input.value}
onChange={props.input.onChange}
onBlur={() => props.input.onBlur(props.input.value)}
options={options}
placeholder="Select"
simpleValue
/>
}
/>
@paothegit @kandaraj it doesn't work with multi-select because of onChange.
I answered how correct to use multi-select react-select in 82 issue.
Here is a component I created to integrate React Select with Redux Form.
This is how you can use it, and it works with both single and multi select.
const fruits = [
{ value: 'apples', label: 'Apples' },
{ value: 'bananas', label: 'Bananas' },
{ value: 'grapes', label: 'Grapes' }
];
<Field
multi={true}
name="fruits"
options={fruits}
component={RFReactSelect} />
Here is an example .... which i implemented for my form:
export class SingleSelect extends Component {
static propTypes = {
name: PropTypes.string,
input: PropTypes.object,
options: PropTypes.array,
handleChange: PropTypes.func,
controlLabel: PropTypes.string,
selectedValue: PropTypes.string
}
onSelectChange = value => {
let { handleChange } = this.props
handleChange(value)
}
render () {
const { options, selectedValue, controlLabel } = this.props
return (
<FormGroup>
<Col md={2} lg={2} mdOffset={1} lgOffset={1}>
<ControlLabel className={'required'} style={{lineHeight: '38px'}}>
{' ' + controlLabel}
</ControlLabel>
</Col>
<Col md={2} lg={3}>
<Select
options={options}
value={selectedValue}
onChange={this.onSelectChange}
/>
</Col>
</FormGroup>
)
}
}
And here is how you can use it in your form
<Row>
<Field
component={SingleSelect}
name={'filterValueSource'}
selectedValue={filter.filterValueSource || ''}
controlLabel={'Filter type'}
options={filterValueSources}
handleChange={this.handleFilterValueSourceSelection}
/>
</Row>
I do not understand why is this issue closed.
It doesn't look like a request for help but rather some gap in the API, as onBlur does not get a regular SyntheticEvent.
Am I wrong?
Of course, the solutions mentioned above do work, thank you.
The takeaway for me on this thread is that onBlur={() => input.onBlur(input.value)}
is required. As soon as I added that I was able to see my values on my redux form submit callback.
Just wanted to post here for posterity - we used the onBlur={() => input.onBlur(input.value)}
solution, and after upgrading to react-select v2 my coworker had a hell of a time trying to figure out why the form state was being reset to nil specifically on Windows machines. Removing that line resolved the issue.
Just wanted to post here for posterity - we used the
onBlur={() => input.onBlur(input.value)}
solution, and after upgrading to react-select v2 my coworker had a hell of a time trying to figure out why the form state was being reset to nil specifically on Windows machines. Removing that line resolved the issue.
@oowowaee Can you tell me why it is especially a problem on windows machines ? We had some weired issues. Did you know which version ?
A bit late to the mix, but I added a small variation to allow redux-form to receive only the value of selected item, instead of both value and label.
In render function :
const formattedOptions = {};
props.options.forEach((obj) => {
formattedOptions[obj.value] = obj;
});
<Select
isClearable
value={formattedOptions[props.input.value]}
onChange={(value) => {
value ?
props.input.onChange(value.value) :
props.input.onChange(null)
}}
onBlur={() => props.input.onBlur(props.input.value)}
onFocues={() => props.input.onFocus(props.input.value)}
options={props.options}
{...props}
/>
@kapalex You saved my bacon! 馃
I did have to make one change because it wasn't handling the case when initial values is null.
<Select
isClearable
- value={formattedOptions[props.input.value]}
+ value={input.value ? formattedOptions[input.value] : null}
onChange={(value) => {
value ?
props.input.onChange(value.value) :
props.input.onChange(null)
}}
onBlur={() => props.input.onBlur(props.input.value)}
onFocuses={() => props.input.onFocus(props.input.value)}
options={props.options}
{...props}
/>
I'm using redux-form: 8.2.0
and react-select: 2.4.3
.
Most helpful comment
For me, the following works for
[email protected]
and[email protected]