zoukankan      html  css  js  c++  java
  • 受控组件和非受控组件

    “受控“组件和”非受控“组件通常是指的表单元素。

    但是有时如果通过props将数据传入某个组件,该组件受props数据控制,也可称为“受控”组件。

    如果只是受state的数据影响,则称为“非受控”组件。

    下面介绍的主要是表单类的组件。

    1. 受控组件

    通过React的state作为数据唯一来源,通过变更函数调用setState方法更新数据的表单输入元素。

    它们的初始值,是this.state的初始值。

    1. input的type="text/number/其他输入格式"的元素,value属性,显示和控制数据; 取值e.target.value;

    2. select元素也通过value控制数据,但是它的value可以通过设置multiple,传入一个数组;取值e.target.value;

    3. textarea元素通过value属性显示和控制数据;取值e.target.value;

    4. type="checkbox"或者"radio", 通过checked属性,显示和控制数据;取值e.target.checked;

    5. 都通过onChange事件属性的处理函数及setState,来更新表单的值;

    6. 如果遇到多个受控组件一起,为了合并使用处理函数,给组件添加name属性;

    7. value或者checked的值如果是undefined或者null,则相当于非受控组件;

       否则,如果不使用处理函数,值无法修改。

    class InputForm extends React.Component{
      constructor(props) {
        super(props);
        this.state = {
          textValue: 'initial',
          checked: false,
          radioed: false,
          areaValue: '',
          selectValue: ''
        }
      }
      handleChangeInput = (e) => {//处理函数
        const target = e.target;
        const type = target.type;
        const checkedTypes = ['radio', 'checkbox'];
        // ['radio', 'checkbox']类型的取值是e.target.value
        // 其余类型的取值是e.target.value
        let value = checkedTypes.includes(type) ? target.checked : target.value;
        console.log(value);
        const name = target.name;
        this.setState({
          [name]: value
        })
      }
      render() {
        return (
          <form>
            {/*所有的受控组件设置一个name属性,用于区分是哪个组件*/}
            <input
              name="textValue"
              type="text" 
              // 使用value传值
              value={this.state.textValue}
              onChange={this.handleChangeInput} 
            /> 
            <input
              name="checked"
              type="checkbox"
              // 使用checked传值
              checked={this.state.checked}
              onChange={this.handleChangeInput}
            />
            <input 
              name="radioed"
              type="radio"
              // 使用checked传值
              checked={this.state.radioed}
              onChange={this.handleChangeInput}
            />  
            <textarea
              name="areaValue"
              // 使用value传值
              value={this.state.areaValue}
              onChange={this.handleChangeInput}
            />  
            <select 
              name="selectValue"
              // 使用value传值
              value={this.state.selectValue}
              onChange={this.handleChangeInput}
            >
              <option value="a">A</option>
              <option value="b">B</option>
              <option value="c">C</option>
              <option value="d">D</option>
            </select>
          </form>  
        )
      }
    }

    2. 非受控组件

    不能通过代码来控制值,只能通过用户行为操作值。通过DOM节点来处理数据。

    1. type="file'的input元素是非受控组件;input的其他类型,当不使用value时,是非受控组件;

    2. type="file"也可以传入multiple属性,传多个文件;

    3. 组件中使用ref属性,获取DOM节点的值;

    4. input[text]/select/textarea,有defaultValue属性在初次渲染时赋予初始值;

        input[checkbox][radio], 有defaultChecked属性来赋初值;

    class InputForm extends React.Component{
      constructor(props) {
        super(props);
        this.inputRef = React.createRef();
        this.fileRef = React.createRef();
        this.selectRef = React.createRef();
        this.checkRef = React.createRef();
      }
      handleSubmit = (e) => {
        e.preventDefault(); //阻止表单默认提交
        const inputValue = this.inputRef.current.value;
        const selectValue = this.selectRef.current.value;
        const files = this.fileRef.current.files[0]; //单个文件
        const checkValue = this.checkRef.current.checked;
        console.log(inputValue,files,selectValue,checkValue)
      } 
      render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <input
              type="text"
              // defaultValue初值
              defaultValue="输入"
              ref={this.inputRef}
            /> 
            <input
              type="checkbox"
              // defaultChecked初值
              defaultChecked
              ref={this.checkRef}
            /> 
            <input
              type="file"
              ref={this.fileRef}
            /> 
            <select 
              defaultValue="c" //初值
              ref={this.selectRef}
            >
              <option value="a">A</option>
              <option value="b">B</option>
              <option value="c">C</option>
              <option value="d">D</option>
            </select>
            <input type='submit'/>
          </form>  
        )
      }
    }

     3. 使用场景

    只能使用受控组件:

    1. 即时的表单字段校验(取值范围等)

    2. 强制输入格式校验

    3. 按条件禁用按钮等

  • 相关阅读:
    CentOS7.6安装Kubernetes v1.15.1
    数据库三大范式
    linux
    linux
    linux
    linux
    Django contenttypes组件
    Django自带的用户认证
    Django rest framework(7) ---分页
    Django rest framework(6) ---序列化
  • 原文地址:https://www.cnblogs.com/lyraLee/p/11570298.html
Copyright © 2011-2022 走看看