浅谈react受控组件与非受控组件(小结)


Posted in Javascript onFebruary 09, 2018

我们都知道,有许多的web组件可以被用户的交互发生改变,比如:<input>,<select>,或者是我现在正在使用的富文本编辑器。这些组件在日常的开发中很不显眼,我们可以很轻易的通过输入一些内容或者设置元素的value属性来改变组件的值。但是,因为React是单向数据流绑定的,这些组件可能会变得失控:

1.一个维护它自己state里的value值的<Input>组件无法从外部被修改;

2.一个通过props来设置value值的<Input>组件只能通过外部控制来更新。

最近在使用蚂蚁金服出品的一条基于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组件的onChange和setState方法来完成对组件的控制;例如对上面形式可以进行封装一个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来创建。

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

  1. 受控元素,一般用在需要动态设置其初始值的情况;例如某些form表单信息编辑时,input表单元素需要初始显示服务器返回的某个值然后进行编辑。
  2. 非受控元素, 一般用于无任何动态初始值信息的情况; 例如form表单创建信息时,input表单元素都没有初始值,需要用户输入的情况

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js url传值中文乱码之解决之道
Nov 20 Javascript
JavaScript中yield实用简洁实现方式
Jun 12 Javascript
ECMAScript中函数function类型
Jun 03 Javascript
微信小程序 聊天室简单实现
Apr 19 Javascript
jQuery实现简单的下拉菜单导航功能示例
Dec 07 jQuery
JS实现的透明度渐变动画效果示例
Apr 28 Javascript
JS与CSS3实现图片响应鼠标移动放大效果示例
May 04 Javascript
vscode下的vue文件格式化问题
Nov 28 Javascript
javascript获取select值的方法完整实例
Jun 20 Javascript
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
layui实现下拉复选功能的例子(包括数据的回显与上传)
Sep 24 Javascript
Vue 嵌套路由使用总结(推荐)
Jan 13 Javascript
基于Vue2.X的路由和钩子函数详解
Feb 09 #Javascript
Vuejs 单文件组件实例详解
Feb 09 #Javascript
vue-lazyload图片延迟加载插件的实例讲解
Feb 09 #Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
Feb 09 #Javascript
在Vue中使用highCharts绘制3d饼图的方法
Feb 08 #Javascript
vue中使用ueditor富文本编辑器
Feb 08 #Javascript
React Native自定义控件底部抽屉菜单的示例
Feb 08 #Javascript
You might like
PHP+DBM的同学录程序(3)
2006/10/09 PHP
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
PHP使用mysql_fetch_object从查询结果中获取对象集的方法
2015/03/18 PHP
浅谈PHP接收POST数据方式
2015/06/05 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
Laravel核心解读之异常处理的实践过程
2019/02/24 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
来自qq的javascript面试题
2010/07/24 Javascript
JavaScript学习笔记之获取当前目录的实现代码
2010/12/14 Javascript
js不能跳转到上一页面的问题解决方法
2013/03/01 Javascript
js禁止页面刷新与后退的方法
2015/06/08 Javascript
浅谈AngularJS中ng-class的使用方法
2016/11/11 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
JS判断Android、iOS或浏览器的多种方法(四种方法)
2017/06/29 Javascript
JavaScript 自定义事件之我见
2017/09/25 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
vant-ui组件调用Dialog弹窗异步关闭操作
2020/11/04 Javascript
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
Python使用htpasswd实现基本认证授权的例子
2014/06/10 Python
python批量生成本地ip地址的方法
2015/03/23 Python
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
一文带你了解Python中的字符串是什么
2018/11/20 Python
Python设计模式之抽象工厂模式原理与用法详解
2019/01/15 Python
pandas的to_datetime时间转换使用及学习心得
2019/08/11 Python
python实现模拟器爬取抖音评论数据的示例代码
2021/01/06 Python
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
英国奢侈皮具品牌:Aspinal of London
2018/09/02 全球购物
销售会计工作职责
2013/12/02 职场文书
服务行业个人求职的自我评价
2013/12/12 职场文书
学校周年庆活动方案
2014/08/22 职场文书
2014年财务人员工作总结
2014/11/11 职场文书
2016消防宣传标语口号
2015/12/26 职场文书
go select编译期的优化处理逻辑使用场景分析
2021/06/28 Golang
Meta增速拉垮,元宇宙难当重任
2022/04/29 数码科技