Props是React组件的参数,而一个组件还可能拥有其内部状态。这里的状态是抽象的状态,不只仅指state(欢迎补充例子)。react
Props能够由外部调用者改变,可是组件本身不能改变本身接收到的Props,虽然组件能够监听Props的改变。相反,组件能够改变本身的状态,而外部调用者却不该该直接改变组件内部状态。composer
在传统的对象模型里,对象间能够互相传递消息,消息接收者受控地改变状态。固然,React组件也能够定义方法,可是尽可能不要这样作,由于React整个体系是由数据流(props流)驱动的,而一个经过消息(方法调用)来驱动的组件,会破坏整个体系,致使同步和适配工做、项目复杂度大增。好比,作代理组件,props很容易向下传递,而methods却须要从新定义。再好比,在container模式,若是一个UI组件是由方法驱动的,那么将很难将其封装为container,由于composer只负责中介数据,却很难维持组件实例的引用。编辑器
综上,咱们但愿构建没有公共方法,仅受props控制的组件。函数
在其余props不变的状况下,组件的一个prop应该和其一组状态有一个一一映射关系。post
纯属性,即不控制任何内部状态。性能
受控属性,即该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的等价比较有时也并不简单,好比包含类对象或函数。所以,若非有特殊需求,这类属性作成一次性属性便可。
说了这么多,在实战中,仍是要根据具体状况灵活变通,关键是,知道的越多,办法越多越好。