React(三):受控组件与非受控组件

一、受控组件html

在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会维持自身状态,并根据用户输入进行更新。但在React中,可变的状态一般保存在组件的状态属性中,而且只能用 setState() 方法进行更新。react

咱们经过使react变成一种单一数据源的状态来结合两者。React负责渲染表单的组件仍然控制用户后续输入时所发生的变化。相应的,其值由React控制的输入表单元素称为“受控组件”。segmentfault

因为 value 属性是在咱们的表单元素上设置的,所以显示的值将始终为 React数据源上this.state.value 的值。因为每次按键都会触发 handleChange 来更新当前React的state,所展现的值也会随着不一样用户的输入而更新。bash

<input type="text" value={this.state.value} onChange={this.handleChange}  />复制代码

二、非受控组件架构

要编写一个非受控组件,而非为每一个状态更新编写事件处理程序,你能够 使用 ref 从 DOM 获取表单值。
dom

在 React 的生命周期中,表单元素上的 value 属性将会覆盖 DOM 中的值。使用非受控组件时,一般你但愿 React 能够为其指定初始值,但再也不控制后续更新。要解决这个问题,你能够指定一个 defaultValue 属性而不是 value
性能

<input type="text" defaultValue={'1232'} ref={this.input} />复制代码

举例:ui

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleChange = this.handleChange.bind(this);
    
    this.input = React.createRef();
    this.state = {
      value:'567'
    }
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
  }
  
  handleChange(e){
     this.setState({value: e.target.value});
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" defaultValue={'1232'} ref={this.input} />
          <input type="text" value={this.state.value} onChange={this.handleChange}  />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);复制代码

在 CodePen 上尝试。
this

三、对比受控组件和非受控组件spa

将输入的字母转化为大写展现

<input
    type="text"
    value={this.state.value}
    onChange={(e) => {
        this.setState({
            value: e.target.value.toUpperCase(),
        });
    }}
/>复制代码

直接展现输入的字母

<input
    type="text"
    defaultValue={this.state.value}
/>复制代码

a、性能上的问题

在受控组件中,每次表单的值发生变化,都会调用一次onChange事件处理器,这确实会带来性能上的的损耗,虽然使用费受控组件不会出现这些问题,但仍然不提倡使用非受控组件,这个问题能够经过Flux/Redux应用架构等方式来达到统一组件状态的目的.

b、是否须要事件绑定

使用受控组件须要为每个组件绑定一个change事件,而且定义一个事件处理器来同步表单值和组件的状态,这是一个必要条件.固然,某些状况可使用一个事件处理器来处理多个表单域


import React, { Component } from 'react';

class Controlled extends Component {
    constructor(...args) {
        super(...args);
        this.state = {
            name: 'xiaoming',
            age: 18,
        };
    }
    handleChange = (name, e) => {
        const { value } = e.target;
        this.setState({
            [name]: value,
        });
    }
    render() {
        const { name, age } = this.state;
        return (
            <div>
                <input type="text" value={name} onChange={this.handleChange.bind(this, 'name')} />
                <input type="text" value={age} onChange={this.handleChange.bind(this, 'age',)} />
            </div>
        );
    }
}

export default Controlled;复制代码


参考:

https://segmentfault.com/a/1190000012404114#articleHeader2

https://react.docschina.org/docs/uncontrolled-components.html

相关文章
相关标签/搜索