美文网首页
React受控组件与不受控组件

React受控组件与不受控组件

作者: Coder_不易 | 来源:发表于2017-12-13 17:43 被阅读377次

    受控组件与不受控组件

    Follow me on GitHub

    1. 受控组件(Controlled Components)

    在HTML中,表单组件<input>,<textarea>,<select>拥有自身的状态(值),并根据用户的输入进行更新。而在React中,可变状态保存在state中,并只能使用setState()来更新。

    我们可以将这两种状态合一,使React的state成为单一数据源(single source of truth),这时渲染form的React组件就可以对表单中的输入进行控制。因此,受控组件就是值受React控制的表单输入元素。

    受控组件通过change事件(在用户输入每个字符时触发)和value属性实现。

    class NameForm extends React.Component{
        constructor(props){
            super(props);
            this.state = {
                name:'',
                sex:'male',
                profile:''
            };
            this.handleNameChange = this.handleNameChange.bind(this);
            this.handleSexChange = this.handleSexChange.bind(this);
            this.handleProfileChange = this.handleProfileChange.bind(this);
        },
        handleNameChange(e){
            this.setState({name:e.target.value});
        },
        handleSexChange(e){
            this.setState({sex:e.target.value});
        },
        handleProfileChange(e){
            this.setState({profile:e.target.value});
        },
        render(){
            return (
                <form onSubmit={this.handleSubmit}>
                    <label>
                        Name:
                        <input type="text"
                            value={this.state.name}
                            onChange={this.handleNameChange}
                        />
                    </label>
                    <label>
                        Sex:
                        <select value={this.state.sex} onChange={this.handleSexChange}>
                            <option value="male">male</option>
                            <option value="female">female</option>
                        </select>
                    </label>
                    <label>
                        Profile:
                        <textarea value={this.state.profile}
                            onChange={this.handleProfileChange}
                        />
                    </label>
                    <input type="submit" value="Submit" />
                </form>
            )
        }
    }
    

    受控组件通过value属性控制输入元素的值,通过change事件处理函数处理所有的用户输入。
    如果value设置为一个固定的值,而未设置其change事件处理函数来设置state,输入元素是不可编辑的。
    value属性在设置为null或者undefined时,输入元素仍旧是可编辑的。

    受控组件需要编写每个输入元素的处理函数,比较繁琐,对于某些输入处理逻辑相同的元素,可通过name属性统一处理。

    class MultipleInput extends React.Component{
        constructor(props){
            super(props);
            this.state = {
                address:'',
                alternateAddress:''
            }
            this.handleChange = this.handleChange.bind(this);
        },
        handleChange(e){
            this.setState({
                [e.target.name]:e.target.value
            });
        }
        render(){
            return (
                <form>
                    <label>
                        address:
                        <input type="text"
                            name="address"
                            value={this.state.address}
                            onChange={this.handleChange}
                        />
                    </label>
                    <label>
                        alternate address:
                        <input type="text"
                            name="alternateAddress"
                            value={this.state.alternateAddress}
                            onChange={this.handleChange}
                        />
                    </label>
                </form>
            );
        }
    }
    

    2. 不受控组件(Uncontrolled Components)

    受控组件表单的值由React控制,不受控组件表单的值由DOM控制,其单一数据源保存在DOM中。
    不受控组件不需要对每个输入元素编写change事件处理函数来更新状态。在需要获取输入元素的值时可使用ref

    class NameForm extends React.Component {
      constructor(props) {
        super(props);
        this.handleSubmit = this.handleSubmit.bind(this);
      }
    
      handleSubmit(event) {
        alert('A name was submitted: ' + this.input.value);
        event.preventDefault();
      }
    
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <label>
              Name:
              <input type="text" ref={(input) => this.input = input} />
            </label>
            <input type="submit" value="Submit" />
          </form>
        );
      }
    }
    

    React的value属性会覆盖DOM中表单输入元素的value值。使用不受控组件时,可使用defaultValue属性来指定初始值。

    3. 使用场景

    场景 受控组件 不受控组件
    one-time value retrieval (e.g. on submit)
    validating on submit
    instant field validation
    conditionally disabling submit button
    enforcing input format
    several inputs for one piece of data
    dynamic inputs

    可参考controlled versus uncontrolled inputs

    相关文章

      网友评论

          本文标题:React受控组件与不受控组件

          本文链接:https://www.haomeiwen.com/subject/lijzixtx.html