React:纯属性(pure prop),受控属性(controlled prop),半受控属性(half-controlled prop),一次性属性(onetime-prop)

Props是React组件的参数,而一个组件还可能拥有其内部状态。这里的状态是抽象的状态,不仅仅指state(欢迎补充例子)。

Props可以由外部调用者改变,但是组件自己不能改变自己接收到的Props,虽然组件可以监听Props的改变。相反,组件可以改变自己的状态,而外部调用者却不应该直接改变组件内部状态。

在传统的对象模型里,对象间可以互相传递消息,消息接收者受控地改变状态。当然,React组件也可以定义方法,但是尽量不要这样做,因为React整个体系是由数据流(props流)驱动的,而一个通过消息(方法调用)来驱动的组件,会破坏整个体系,导致同步和适配工作、项目复杂度大增。比如,做代理组件,props很容易向下传递,而methods却需要重新定义。再比如,在container模式,如果一个UI组件是由方法驱动的,那么将很难将其封装为container,因为composer只负责中介数据,却很难维持组件实例的引用。

综上,我们希望构建没有公共方法,仅受props控制的组件。

在其他props不变的情况下,组件的一个prop应该和其一组状态有一个一一映射关系。

纯属性,即不控制任何内部状态。

受控属性,即该prop和组件的部分状态始终按某种一一映射保持一致。比如,prop是userId,而内部状态包含这个用户的nickname和email,则userId不变,nickname,email不变,userId变,nickname,email按userId改变(不是随便变)。

半受控属性,相比于受控属性,prop变化时,对应的状态会更新为对应状态,但是在prop未改变时,这些状态却可以自由变化。比如prop是postId,状态是content,则content可能受到自由的编辑,但是postId改变时,content又会被更新为与新postId一致。

一次性属性,相比于受控属性,状态被设置到与该prop同步,只在组件mount时发生一次。

理论上,我们希望保持组件越纯越好,能做成纯组件的,尽量做成纯组件,不能的,至少也要做成受控组件。但是在实际的生产实践中,由于一些原因,我们还是被迫接受了制作半受控组件和一次性组件,比如封装某些非react组件,抑或某些操作类组件内部状态过多,处于性能考虑或其他bug,不便于频繁与应用状态保持同步。

比如说,对一个本身内容可自由变化的文本编辑器进行封装,其content很可能被设计为半受控属性,如此一来,虽然如果编辑器内容改变,而prop强行保持不变,会导致不一致问题,但大部分实际用例却是另一番景象:编辑器内容改变->触发onChange事件->prop改变->prop与编辑器内容一致,因此不需要更新编辑器内容。这样效率高,而且也保持了正常用例下的状态同步,在实际生产实践中是可取的。相比较,如果强行制作为受控组件,则需要附加很tricky的代码,增加复杂度,牺牲性能。

再比如,封装一些带options的组件,通常这个options会被设计为一次性参数,因为这些options的在原始组件中的设计初衷就是在组件创建时进行初始化设置,并没有要求组件在创建后还可以通过update options等类似方式来更新组件,在正常用例下,是没有什么问题的。如果强行做成半受控及其以上属性,则在options更新时,该组件实际上也必须销毁重构,而且,options的等价比较有时也并不简单,比如包含类对象或函数。因此,若非有特殊需求,这类属性做成一次性属性即可。

说了这么多,在实战中,还是要根据具体情况灵活变通,关键是,知道的越多,办法越多越好。

时间: 2024-08-10 23:29:23

React:纯属性(pure prop),受控属性(controlled prop),半受控属性(half-controlled prop),一次性属性(onetime-prop)的相关文章

以属性为核心驱动的 全领域通用架构设计原理 (简称:属性架构原理)

以属性为核心驱动的全领域通用架构设计原理 (简称:属性架构原理) 联系方式:13547930387 Email:[email protected] 一.个人声明 我,参加工作也有5年多了,是一名普通的不能在普通的程序员,一直在使用公司自己的产品进行开发,因此技术比较菜,此设计完全是按照自己天真的想法而设计的,如果有不合理或很搞笑的地方,请轻拍,由衷的希望大家能提出宝贵的意见: 根据此设计原理我也做了一个简单的(demo)架构来支撑和验证此理论的可行性,由于技术功底不太好,有不合理之处请大家谅解,

DOM访问HTML元素的方式,DOM访问表单控件的常用属性和方法,DOM访问列表框、下拉菜单的常用属性,DOM访问表格子元素的常用属性和方法,DOM对HTML元素的增删改操作

DOM访问HTML元素的方式 为了动态地修改HTML元素,须先访问HTML元素.DOM主要提供了两种方式来访问HTML元素: 根据ID访问HTML元素:通过document对象调用getElementById()方法来查找具有唯一id属性值的元素. 利用节点关系访问HTML元素.常用的属性和方法如下: parentNode 返回当前节点的父节点 previousSibling 返回当前节点的前一个兄弟节点 nextSibling 返回当前节点的后一个兄弟节点 childNodes 返回当前节点的

Web 前端技术:CSS3---新属性,浏览器支持度,圆角边框(border-radius),阴影(box-shadow),文字与字体(text-shadow属性、word-wrap属性、@font-face规则),2D转换、过渡与动画(transform属性),3D变换

浏览器支持度 CSS3属性: columns:规定列的宽度和列数 默认宽度.列数值为auto column-width:每栏的宽度 column-gap :两栏之间的间距距离 column-count : 栏目的数目 column-rule : color(色值) width(宽度) style(线条样式) 分栏中的分割线的颜色宽度及样式的设定 1.border-radius属性(圆角边框) eg: 结合不同浏览器兼容问题,使用该CSS3新属性 eg: 2.box-shadow属性(阴影) eg

react纯前端不依赖于打包工具的代码

####react最基础的语法和不依赖环境的纯前端免编译代码 参照:http://www.ruanyifeng.com/blog/2015/03/react.html 注意事项:1.必须放倒服务器上,在文件系统上无法运行 login.html <!doctype html> <head> <meta charset="utf-8"> <script src="https://npmcdn.com/[email protected]/d

laravel--为什么属性在模型中没有定义,却取出来了值,这些属性哪里来的

看laravel模型中的这段代码, public function getLimitUsersAttribute() { return $this->user_limit - $this->user_count; } 但是模型中确没有定义, 那么user_limit和user_count属性,是从哪里来的?laravel本身一种机制,可以直接在模型当中调用数据库里字段,这个属性就是Lesson模型对应的lession表里的2个字段 使用一下看看,控制器是这样来使用 方法在看一看 那么这样输出的

react纯手写全选与取消全选

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

初学knockoutjs记录7——Computed observables依赖监控(4 Pure computed observables 纯计算监控属性)

Pure computed observables 纯计算监控属性 纯计算监控属性在knockout3.2.0中引入,给在大多数场合下常规的计算监控属性提供了一个速度和内存性能更好选择.这是因为纯计算监控属性在它本身没有被订阅的情况下不需要维护它的依赖. 它的特性: Prevents memore leaks 防止内存泄露.纯计算监控属性不再是一个程序引用,但是它的整个依赖依然存在. Reduces computation oberhead 减少计算开销.当值不再被监控时不再进行计算监控属性的计

react学习记录(三)——状态、属性、生命周期

react的状态state React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM) class Clock extends React.Component { constructor(props) { super(props); this.state = {date: new Date()}; } componentDidMount() { this.timerID = setInterval( () => this.tick(), 1000

jquery13 attr() prop() val() addClass()等 : 对元素属性的操作

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>无标题文档</title> <script src="jquery-2.0.3.js"></script> <script> jQu