I am trying to use creatable, but the option to add new item does not show.
Am I missing something?
`
render() {
return (
<Creatable
multi={true}
options={this.state.options}
onChange={this.handleSelectChange.bind(this)}
value={this.state.backupsSelected}
valueKey="email"
labelKey="email"
isLoading={this.state.isLoading}
newOptionCreator={this.newOption.bind(this)}
/>
);
}
It does work. Pl check if this fiddle helps. If you can paste a fiddle of your code it would be easier to identify the issue,,
https://jsfiddle.net/vivekmoosani/4hvtauob/
Thanks, that helped!!
I have tried the same thing I get the following error.
warning.js:45Warning: React.createElement: type should not be null, undefined, boolean, or number. It should be a string (for DOM elements) or a ReactClass (for composite components). Check the render method of
MyComponent.
invariant.js:39Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. Check the render method of
MyComponent.
This is my code
import React,{Component} from 'react';
import Select from 'react-select';
class MyComponent extends Component{
constructor(){
super();
this.state = {
"value":""
};
}
handleOnChange = (value) => {
this.setState({
"value":value
});
}
render(){
const {value} = this.state;
let options = [
{ value: 'R', label: 'Red' },
{ value: 'G', label: 'Green' },
{ value: 'B', label: 'Blue' }
]
return(
<Select.Creatable
options={options}
onChange={this.handleOnChange}
value={value}/>
)
}
}
Instead if I do the following then it works fine i.e. with
allowCreate={true}
<Select allowCreate={true}
options={options}
onChange={this.handleOnChange}
value={value}/>
What am I doing wrongAny help would be good.
just incase others come here, the take away from the fiddle is that you need to add the value to the state and concat it to the options prop to the select:
handleOnChange = (value) => {
this.setState({
value,
createdOptions: value, // you can do this a lot smarter
})
}
render () {
return (
<Createable
options={this.props.options.concat(this.state.createdOptions.map(option => ({
value: option,
label: option
})))}
value={this.state.value}
multi
handleOnChange={this.handleOnChange}
/>
)
}
or something like that
i got stuck on this as well when using Creatable with redux-form . creating a new option worked, but when blurring the Field the input value was blanked. i had to keep track of createdOptions in local state and concat it with props.options so that the new options weren't lost on re-render.
most of this source is from another author - someone either on SO or in the issues here but i can find his name atm to give credit. i added the onNewOptionClick callback and local state.
component:
import React, { Component, PropTypes } from 'react';
import Select from 'react-select';
import 'react-select/dist/react-select.css';
class RFReactSelect extends Component {
constructor() {
super()
this.state = {
createdOptions: []
}
this.onNewOptionClick = this.onNewOptionClick.bind(this)
}
render() {
const { input , options, multi, className,
newOptionCreator, promptTextCreator, isValidNewOption } = this.props
const { name, value, onBlur, onChange, onFocus } = input;
const allOptions = options.concat(this.state.createdOptions)
const transformedValue = transformValue(value, allOptions, multi);
return (
<Select.Creatable
className={className}
isValidNewOption={isValidNewOption}
multi={multi}
name={name}
newOptionCreator={newOptionCreator}
onSelectResetsInput={false}
onBlurResetsInput={false}
options={allOptions}
onChange={multi
? multiChangeHandler(onChange)
: singleChangeHandler(onChange)
}
onBlur={() => onBlur(value)}
onFocus={onFocus}
onNewOptionClick={this.onNewOptionClick}
promptTextCreator={promptTextCreator}
ref='creatable'
value={transformedValue}
valueKey='value'
/>
);
}
/**
* Keep created options in local state or they will be lost
* on re-render
*/
onNewOptionClick(option) {
const { props, select } = this.refs.creatable
const { options } = props
options.unshift(option)
select.selectValue(option)
this.setState({
createdOptions: [option]
})
}
}
/**
* onChange from Redux Form Field has to be called explicity.
*/
function singleChangeHandler(func) {
return function handleSingleChange(option) {
func(option ? option.value : '');
};
}
/**
* onBlur from Redux Form Field has to be called explicity.
*/
function multiChangeHandler(func) {
return function handleMultiHandler(values) {
func(values.map(value => value.value));
};
}
/**
* For single select, Redux Form keeps the value as a string, while React Select
* wants the value in the form { value: "grape", label: "Grape" }
*
* * For multi select, Redux Form keeps the value as array of strings, while React Select
* wants the array of values in the form [{ value: "grape", label: "Grape" }]
*/
function transformValue(value, options, multi) {
if (multi && typeof value === 'string') return [];
const filteredOptions = options.filter(option => {
return multi
? value.indexOf(option.value) !== -1
: option.value === value;
});
return multi ? filteredOptions : filteredOptions[0];
}
RFReactSelect.defaultProps = {
multi: false,
className: ""
};
RFReactSelect.propTypes = {
input: PropTypes.shape({
name: PropTypes.string.isRequired,
onBlur: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
onFocus: PropTypes.func.isRequired,
}).isRequired,
options: PropTypes.array.isRequired,
multi: PropTypes.bool,
className: PropTypes.string,
onNewOptionClick: PropTypes.func,
}
export default RFReactSelect
used with redux-form's Field
<Field
className={styles.RFReactSelect}
component={RFReactSelect}
name='client'
options={clientOptions}
validate={required({ msg: 'Client Email is required' })}
{
...{
isValidNewOption,
newOptionCreator,
promptTextCreator,
}
}
Most helpful comment
just incase others come here, the take away from the fiddle is that you need to add the value to the state and concat it to the
optionsprop to the select:or something like that