React 受控与非受控组件

110 阅读1分钟

React 组件可以根据是否受控,分为受控组件与非受控组件

  • 受控组件

    组件状态受外部环境的控制

  • 非受控组件

    组件有自己的内部状态,并且不受外部环境的控制

需要受控组件的场景更多一些,比如在进行表单数据管理的时候,接下来来看看受控组件与非受控组件区别。

非受控组件

如果使用非受控组件,需要使用 ref 的方式来获取表单数据(ref属性可以获取子组件的实例或 DOM 对象)

其中 event.preventDefault() 的作用是阻止默认行为, 防止数据提交后页面刷新。具体实现如下:

export class App extends myComponent {
    constructor() {
        this.userName = React.createRef()
        this.password = React.createRef()
    }

    submit = ()=>{
        event.preventDefault();
        console.log(this.userName.current.value);
        console.log(this.password.current.value);
    }

    render() {
        return (
          <div>
            <form onSubmit = { this.submit }>
                <input type = "text" ref = { this.userName }></input>
                <input type = "password" ref = { this.password }></input>
                <button type = "submit">提交</button>
            </form>
          </div>
        )
    }
}

运行结果:

1681450952773.png

1681450965392.png

注:函数式组件没有实例(组件直接返回了React元素),无法使用 ref

受控组件

受控组件类似于双向绑定的效果

  • 更改文本框内的值 ——> 执行 onChange 中绑定的事件 ——> 更新状态值(通过setState()实现)——> 重新渲染视图
  • 某个操作后状态值改变(通过setState()实现)——> 文本框内的值更新(因为value 绑定的就是 state 中的对应字段)。

与非受控组件不同的是:

  1. 受控组件需要在表单上使用 onChange 来绑定事件,
  2. 组件的 value 绑定 state 的对应字段

具体实现代码如下:

export default class Demo extends React.Component {
    constructor(props){
        super(props);
        this.userName = React.createRef()
        this.password = React.createRef()
        this.state = {
            keyword:'默认值'
        }
    }
    render() {
        return <>
            <form onSubmit={this.submit}>
                <input value={this.state.keyword} onChange={(event)=>{
                    this.setState({
                        keyword: event.target.value
                    })
                }} />
                <button type="submit">提交</button>
            </form>
        </>
    }
    submit = (event)=>{
        event.preventDefault();
        console.log(this.state.keyword);
    }
}

运行结果:

1681451127037.png

1681451143142.png