kurumkan
kurumkan

Reputation: 2725

React contolled component change value of select

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

Answers (1)

gaperton
gaperton

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

Related Questions