# 详解受控组件及各种表单中的使用

# 受控组件

在React中是如何实现表单操作的呢?主要就是利用受控组件来完成的,那么受控组件需要采用value + onChange的一个组合。

class Welcome extends React.Component {
    state = {
        msg: 'hello'
    }
    handleChange = (ev) => {
        this.setState({
            msg: ev.target.value
        });
    }
    render(){
        return (
            <div>
                <input type="text" value={this.state.msg} onChange={this.handleChange} /> { this.state.msg }
            </div>
        );
    }
}

这样当输入框输入内容后,数据会跟着发生改变,从而视图也会跟着放生变化。

那么这种受控组件也可以针对除了输入框以外的其他表单控件,如:下拉菜单,单选按钮,多选按钮,下面分别来看一下。

// 受控的下拉菜单
class Welcome extends React.Component {
    state = {
        city: '上海'
    }
    handleChange = (ev) => {
        this.setState({
            city: ev.target.value
        });
    }
    render(){
        return (
            <div>
                <select value={this.state.city} onChange={this.handleChange}>
                    <option value="北京">北京</option>
                    <option value="上海">上海</option>
                    <option value="深圳">深圳</option>
                </select>
                { this.state.city }
            </div>
        );
    }
}
// 受控的单选按钮
class Welcome extends React.Component {
    state = {
        gender: '女'
    }
    handleChange = (ev) => {
        this.setState({
            gender: ev.target.value
        });
    }
    render(){
        return (
            <div>
                <input type="radio" name="gender" value="" onChange={this.handleChange} checked={this.state.gender === '男'} /><input type="radio" name="gender" value="" onChange={this.handleChange} checked={this.state.gender === '女'} /><br />
                { this.state.gender }
            </div>
        );
    }
}
// 受控的多选按钮
class Welcome extends React.Component {
    state = {
        furits: ['苹果', '西瓜']
    }
    handleChange = (ev) => {
        if(ev.target.checked){
            this.setState({
                furits: [...this.state.furits, ev.target.value] 
            });
        }
        else{
            let furits = [...this.state.furits];
            furits.splice(furits.indexOf(ev.target.value), 1)
            this.setState({
                furits
            });
        }
    }
    render(){
        return (
            <div>
                <input type="checkbox" value="苹果" onChange={this.handleChange} checked={ this.state.furits.includes('苹果') } /> 苹果
                <input type="checkbox" value="香蕉" onChange={this.handleChange} checked={ this.state.furits.includes('香蕉') } /> 香蕉
                <input type="checkbox" value="西瓜" onChange={this.handleChange} checked={ this.state.furits.includes('西瓜') } /> 西瓜
                <input type="checkbox" value="葡萄" onChange={this.handleChange} checked={ this.state.furits.includes('葡萄') } /> 葡萄
                <br />
                { this.state.furits }
            </div>
        );
    }
}