Reputation: 2725
I have controlled component(I hope I understood the concept correctly). Here is fragment of app.js (parent(main) component).
...
<Select options={this.state.patterns}
default={this.state.activePattern} select={this.selectPattern}/>
Here is Select component. It is controlled - am I right?
var Select = React.createClass({
getInitialState(){
return {
value: this.props.default
};
},
handleChange(e){
var value = e.target.value;
this.setState({value: value});
this.props.select(value);
},
render(){
return (
<select value={this.state.value} onChange={this.handleChange}>
{this.props.options.map(
(option, i)=>(
<option value={option} key={i}>
{option}
</option>
)
)}
</select>
);
}
});
When user selects something - handleChange got called and we are happy.
But I also want to be able to change selected value from my app.js. How can I make that?
Upvotes: 1
Views: 3087
Reputation: 3826
Three ways.
1) "Bad".
Create the ref to the select at the upper level, and then call setState
directly. `this.refs.mySelect.setState({ value : whaever });
2) "Better".
Manage the state at the upper level. Remove selection state (value) from the Select local state, and expose it through the props together with select
callback. No additional lifecycle hooks (like componentWillReceiveProps
) are actually required for that, you just need to remove something you don't need. Like this:
var Select = React.createClass({
handleChange(e){
var value = e.target.value;
this.props.select(value);
},
render(){
return (
<select value={this.props.value} onChange={this.handleChange}>
{this.props.options.map(
(option, i)=>(
<option value={option} key={i}>
{option}
</option>
)
)}
</select>
);
}
});
3) "Best".
Use value links pattern to hide annoying callbacks. Some good libraries may be helpful:
var Select = ({ options, valueLink }) => (
<select value={ valueLink.value } onChange={ valueLink.action( ( x, e ) => e.target.value }>
{ options.map(
(option, i)=>(
<option value={option} key={i}>
{option}
</option>
)
)}
</select>
);
Upvotes: 2