這篇文章寫的較早,是剛接觸RN的時候進行的思考總結,是一個分析的過程,您還能夠參考思想更成熟一點的這篇:RN組件架構設計:http://segmentfault.com/a/1190000004161358html
設計React組件與設計一個jquery組件或者一個原生js組件最大的區別就是狀態的設計。react
屬性jquery
泛指用戶在初始化組件時候能夠傳給組件的git
有些框架也叫optionsgithub
是public的算法
在RN體系中,叫props,其中還包含了事件segmentfault
事件數組
是public的架構
是function類型的框架
在RN體系中使用props來引用
接口
是public的
是function類型的
經過組件實例化以後的對象,能夠進行調用
內部屬性
是private的
傳統設計方案中通常用於存儲組件的狀態,數據等
RN體系中沒有對其進行明確,能夠自由設計
狀態
RN體系中明確提出的概念
傳統設計方案中通常使用內部屬性來表示
按照原來設計組件的方法論,一個UI組件對外應該具備屬性、事件、接口,對內具備內部屬性,內部接口。
屬性就像一份配置文件,描述了組件應該具備的功能、外觀或者初始狀態。
事件是組件在工做工程中,當知足某種條件的時候觸發的回調函數
接口是組件對象的方法,可讓組件去執行某個任務
在原來的設計理念中,並無提出組件狀態的概念,可是其也是一直存在的,一般是使用組件私有屬性來存儲。
好比,你設計一個按鈕,那麼他可能有正常狀態,禁用狀態,那麼咱們會設計一個屬性disable={true|false}來通知組件初始化的具備的狀態,設計2個接口disable、enable來賦予js有動態改變其狀態的能力,設計2個事件onEnable、onDisable來通知回調函數組件狀態發生了變化。僞代碼以下:
//組件定義 class button{ constructor(disable,pid){//構造函數 this.disable=disable,//屬性:組件初始化使用這個做爲狀態 this.pid=pid;//屬性:父容器的id this._disable=null,//狀態:私有屬性 if(this.disable==true){//根據屬性來決定初始化狀態 this.disable(); }else{ this.enable(); } this.render();//渲染組件 } enable(){ this._disable=false; if(this.el)this.el.set('disable',false); this.fireEvent('onEnable');//觸發事件 } disable(){ this._disable=true; if(this.el)this.el.set('disable',true); this.fireEvent('onDisable');//觸發事件 } render(){ //渲染組件,狀態直接影響了組件的表現和功能 $(this.pid).innerHTML='<button disable='+this._disable+' />'; //初始化對dom節點的引用 this.el=$(this.pid).getChild(); } } //父容器 <div id='a'></div> //實例化組件並使用 new button(false,'a');
上面的示例中,表示了一個傳統UI組件的設計思路,_disable就是這個button組件的關鍵狀態,它直接影響了組件的表現和行爲。
而react架構直接把組件狀態提高到了一個新的高度,主要有如下幾點:
使用固定的接口來聲明組件狀態和狀態默認值
使用固定的接口來得到和改變組件狀態的值
狀態的改變必定會改變組件的表現,會致使組件的從新渲染
前兩項都不是問題,由於咱們原來也得有這些東西,只不過寫法發生了變化,關鍵是最後一項。這裏說的不是問題,指的是思路上比較容易接受。這種固定寫法,問題也很明顯,由於要想把一個狀態從RN狀態體系拿進拿出,會產生必定的工做成本,非常不爽。
我一直在思索,組件狀態的變化必定要致使view的變化嗎?
答案確定是no,由於有些狀態僅僅影響組件的行爲,並不影響表現。好比說,我賦予按鈕一個新功能,它能夠提交某個表單的數據,也就是須要一個新的狀態formName,他就不影響表現,隻影響行爲。
考慮到性能的極致,咱們就只能把這種狀態放到RN的狀態體系以外,做爲對象的私有屬性存在。
RN號稱diff算法性能很高,但也不是0損耗,若是對RN的渲染理解很透徹,你固然也能夠不這樣設計,可是我這裏仍是傾向於保守一些,不然後期的調整也是有工做量的,由於定義、初始化、取值、改值這些操做代碼都不同。寫到這裏我忽然想到,若是能夠,咱們能夠經過某種方法方便的修改某個狀態是否影響表現,不用改其它代碼的話,那麼咱們設計狀態的時候就不用區分了,就能讓咱們更關注設計自己。
說道這裏,基本能夠理清思路了。
組件按照傳統方式設計,該怎麼設計就怎麼設計,在設計原來組件內部屬性的時候,多考慮一步,哪些內部屬性的改變是影響表現的,哪些內部屬性是不影響表現的。將影響表現的放入到RN狀態體系中,將不影響表現的,放入內部屬性中。便可。
耦合性很強的父子組件,建議將狀態統一放到父組件中,子組件中不要放狀態了,不管是狀態的跨組件共享,仍是對view渲染的觸發都很方便。除非你很肯定某個狀態只子組件內部使用,一般這種狀況後邊可能也會發生變化。
如下問題能夠幫助識別是不是state,摘自官網
是不是從父級經過 props 傳入的?若是是,可能不是 state 。
是否會隨着時間改變?若是不是,可能不是 state 。
能根據組件中其它 state 數據或者 props 計算出來嗎?若是是,就不是 state 。
根據state的特色進行識別,加入到上一條
屬性的改變會影響到view的變化就多是state
參考地址