React 受控组件 && 非受控组件

一、表单

在有交互的Web应用中,表单是必不可少的。但是,在和其他元素相比,表单元素在React中的工作方式存在一些不同。像div、span等非表单元素只需根据组件的属性或状态进行渲染即可,但表单元素自身维护一些状态,而这些状态默认情况下是不受React控制的。例如,input元素会根据用户的输入自动改变显示的内容,而不是从组件的状态中获取显示的内容。我们称这类状态不受React控制的表单元素为非受控组件。在Reac中,状态的修改必须通过组件的state,非受控组件的行为显然有悖于这一原则。为了让表单元素状态的变更也能通过组件的state管理,React采用受控组件的技术达到这一目的。

二、受控组件

如果一个表单元素的值是由React来管理的,那么它就是一个受控组件。React组件渲染表单元素,并在用户和表单元素发生交互时控制表单元素的行为,从而保证组件的state成为世界上所有元素的唯一来源。例如,文本框包含类型为text的input元素和textarea元素。它们受控的主要原理是,通过表单元素的value属性设置表单元素的值,通过表单元素的onChange事件监听值的变化,并将变化同步到React组件的state中。

三、非受控组件

使用受控组件虽然保证了表单元素的状态也由React统一管理,但需要为每个表单元素定义onChange事件的处理函数,然后把表单状态的更改同步到React组件的state,这一过程是比较麻烦的,一种可替代的解决方案是使用非受控组件。非受控组件指表单元素的状态依然由表单元素自己管理,而不是交给React组件管理。使用非受控组件需要有一种方式可以获取到表单元素的值,React中提供了一个特殊的属性ref,用来引用React组件或DOM元素的实例,因此我们可以通过为表单元素定义ref属性获取元素的值。例如:

class SimpleForm extends Component{
      constructor(props){
           super(props);
           this.handleSubmit = this.handleSubmit.bind(this);
      }
     handleSubmit(event){
         alert('The title you submitted was'+this.input.value);
          event.preventDefault();
     }

     render(){
          return(
               
this.input=input} /> ); } }

ref的值是一个函数,这个函数会接收当前元素作为参数,即例子中的input参数指向的是当前元素。在函数中,我们把input赋值给了this.input,进而可以在组件的其他地方通过this.input获取这个元素。
在使用非受控组件时,我们常常需要为相应的表单元素设置默认值,但是无法通过表单元素的value属性设置,因为非受控组件中,React无法控制表单元素的value属性,这也就意味着一旦在非受控组件中定义了value属性的值,就很难保证后续表单元素的值的正确性。这种情况下,我们可以使用defaultValue属性指定默认值。

四、结论

非受控组件看似简化了操作表单元素的过程,但这种方式破坏了React对组件状态管理的一致性,往往容易出现不容易排查的问题,因此非特殊情况下,不建议使用非受控组件。

  • 摘自《React进阶之路》

你可能感兴趣的:(React 受控组件 && 非受控组件)