• 浅谈react受控组件与非受控组件


    引言

    最近在使用蚂蚁金服出品的一条基于react的ant-design UI组件时遇到一个问题,编辑页面时input输入框会展示保存前的数据,但是是用defaultValue就是不起作用,输入框始终为空值而不是具体的传入的值。具体编辑页面中文本框相关的代码如下:

            ... //render方法上面的内容省略
     <FormItem
          label="问题描述:"
          hasFeedback
          {...props.formItemLayout}
     >
        <Input type="textarea" defaultValue={props.value}/>
    </FormItem>
                //render下面的内容省略
                ...
    

    在给代码段所属的组件传递value props后,文本框中的默认值一直为空,因为该页面所在的状态state中,value所对应的状态初始值为空,导致后续异步请求成功后改变value对应的状态中的值,仍然显示为空。

    google一下具体原因,原来React的form表单组件中的defaultValue一经传递值后,后续改变defaultValue都将不起作用,被忽略了

    具体来说这是一种react非受控组件,其状态是在input的react内部控制,不受调用者控制。可以使用受控组件来实现。

    下面就说说这个受控组件与非受控组件,它们都是基于react的form表单组件元素的,具体也可参考react官网这方面介绍

    受控组件

    就形式上来说,受控组件就是为某个form表单组件添加value属性;非受控组件就是没有添加value属性的组件;,受控组件的形式如下形式:

    render: function() {
        return <input type="text" value="Hello!" />;
      }
    

    添加了value 属性的表单组件元素其内部是不会维护自己状态state,组件的value值一旦设置某个具体值就始终是这个值,所以需要调用者来控制组件value的改变。

    这种写法带来一个问题:渲染后的input组件的用户交互,用户输入的任何值将不起作用,input输入框中的值始终为Hello!这与HTML中input表现不一致。

    为此,为了控制该组件,就需要能能够控制input组件的值,需要借助其内部的状态state,即组件内部要维护一个状态state以便配合input组件的onChangesetState方法来完成对组件的控制;例如对上面形式可以进行封装一个inputItem组件,其内部维护一个state状态,具体代码如下:

      export default class InputItem extends React.Component{
        constructor(props){
            super(props);
            this.state = {
                value: ""
            }
        }
    
        componentWillReceiveProps(nextProps){
            this.setState({
                value: nextProps.value
            })
        }
    
        _onChange(evt){
            this.setState({
                value: evt.target.value
            })
        }
    
        render(){
            return (
                <input type="text" 
                    value={this.state.value} 
                    onChange={this._onChange.bind(this)}/>
            );
        }
    }
    

    这样就可以在外部像下面这样调用InputItem组件了:

        <InputItem value={this.state.userName} />
    

    这样就可以控制react的Input组件了,其实就是需要借助react的有状态component来完成,因为有状态component可以内部维护state

    非受控组件

    表现形式上,react中没有添加value属性的表单组件元素就是非受控组件。表现形式如下:

        <input type="text" />
    

    非受控组件在底层实现时是在其内部维护了自己的状态state;这样表现出用户输入任何值都能反应到元素上。

    总结

    在使用react component时,都会遇到受控组件或者非受控组件;在目前,react组件推荐使用stateless component,但是使用该形式来实现react component时使用非受控组件到倒是没有什么大问题,若是需要控制受控元素就会有出现问题,表现在:

    `受控组件`需要主动维护一个内部state状态的,而`stateless component`是无需维护组件的state状态的,二者有冲突。
    

    所以,受控元素就不能使用stateless component来创建。

    鉴于受控组件与非受控组件的特点,二者应用的地方也有所不同,主要表现在:

    • 受控元素,一般用在需要动态设置其初始值的情况;例如某些form表单信息编辑时,input表单元素需要初始显示服务器返回的某个值然后进行编辑。

    • 非受控元素, 一般用于无任何动态初始值信息的情况; 例如form表单创建信息时,input表单元素都没有初始值,需要用户输入的情况

    最后说明一下,本人才疏学浅,有什么不对的地方希望大家批评指正!!!

  • 相关阅读:
    MySQL (一)(未完成)
    HTML 学习笔记 CSS3 (边框)
    HTML 学习笔记 JavaScript (函数)
    HTML 学习笔记 JavaScript (对象)
    HTML 学习笔记 JavaScript (变量)
    HTML 学习笔记 JavaScript (实现)
    HTML 学习笔记 JavaScript(简介)
    iOS RunTime运行时(1):类与对象
    iOS UITableView 分割线从零开始
    HTML 学习笔记 CSS(选择器4)
  • 原文地址:https://www.cnblogs.com/wonyun/p/6023363.html
Copyright © 2020-2023  润新知