受控组件 VS 非受控组件

写在前面

React 中受控组件和非受控组件的概念是针对于表单元素的。
表单元素的工作方式和其他 DOM 元素有些不同,简单来说,其他 DOM 元素的 state 数据都是由开发者直接控制和维护的,但是表单元素的 state 是由表单自己维护的,用户通过输入的方式改变表单的 state 数据。
表单数据默认是由自己维护的,那么能否将表单的数据交给开发者维护呢?这就衍生出受控组件和非受控组件的概念。

官方解释:React 受控组件React 非受控组件

1. 受控组件

受控组件,顾名思义,就是表单组件数据受开发者的控制,也就是说开发者可以通过 JavaScript 对页面中表单的内容进行改变和控制。

<input value={x} onChange={fn}/>

class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {val: ''}  
    } 
    handleChange = (e)=>{
        this.setState({val: e.target.value})
    }
    handleSubmit = (e)=>{
        e.preventDefault();
        console.log(this.state.val)
    }
    handleClick = ()=>{
        this.setState({val: 'vin'})
    }
    render(){
        return (
            <div>
                我是App组件
                <form onSubmit={this.handleSubmit}>
                    <label>
                        名字:<input type="text" value={this.state.val} onChange={this.handleChange}/>
                    </label>
                    <label>
                        <input type="submit"/>
                    </label>
                </form>
                <button onClick={this.handleClick}>改变名字为 vin</button>
            </div>
        )
    }
}

自定义表单组件的受控组件是一样的控制方式

const MyInput = (props)=>{
    return (
        <form onSubmit={props.onSubmit}>
            <label>
                名字:<input type="text" value={props.value} onChange={props.onChange}/>
            </label>
            <label>
                <input type="submit"/>
            </label>
        </form>
    )
}

class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {val: ''}  
    } 
    handleChange = (e)=>{
        this.setState({val: e.target.value})
    }
    handleSubmit = (e)=>{
        e.preventDefault();
        console.log(this.state.val)
    }
    handleClick = ()=>{
        this.setState({val: 'vin'})
    }
    render(){
        return (
            <div>
                我是App组件
                <MyInput value={this.state.val} onChange={this.handleChange} onSubmit={this.handleSubmit}/>
                <button onClick={this.handleClick}>改变名字为 vin</button>
            </div>
        )
    }
}

2. 非受控组件

非受控组件的数据由表单DOM元素自己维护。
非受控组件中若想设置初始值,不能使用 value 属性了,而是使用 defaultValue 属性仅仅进行数据初始化。
通过为表单元素添加 ref 属性的方式访问表单内的数据。

<input defaultValue={x} ref={input}/>

class App extends React.Component{
    constructor(props){
        super(props)
        this.state = {val: ''}  
        this.myRef = React.createRef()
    } 
    handleSubmit = (e)=>{
        e.preventDefault();
        console.log(this.myRef.current.value)
    }
    render(){
        return (
            <div>
                我是App组件
                <form onSubmit={this.handleSubmit}>
                    <label>
                        名字:<input type="text" defaultValue={this.state.val} ref={this.myRef}/>
                    </label>
                    <label>
                        <input type="submit"/>
                    </label>
                </form>
            </div>
        )
    }
}
原文地址:https://www.cnblogs.com/lovevin/p/13519236.html