ReactNative組件狀態設計思考

這篇文章寫的較早,是剛接觸RN的時候進行的思考總結,是一個分析的過程,您還能夠參考思想更成熟一點的這篇:RN組件架構設計:http://segmentfault.com/a/1190000004161358html

設計React組件與設計一個jquery組件或者一個原生js組件最大的區別就是狀態的設計。react

術語定義

  1. 屬性jquery

    1. 泛指用戶在初始化組件時候能夠傳給組件的git

    2. 有些框架也叫optionsgithub

    3. 是public的算法

    4. 在RN體系中,叫props,其中還包含了事件segmentfault

  2. 事件數組

    1. 是public的架構

    2. 是function類型的框架

    3. 在RN體系中使用props來引用

  3. 接口

    1. 是public的

    2. 是function類型的

    3. 經過組件實例化以後的對象,能夠進行調用

  4. 內部屬性

    1. 是private的

    2. 傳統設計方案中通常用於存儲組件的狀態,數據等

    3. RN體系中沒有對其進行明確,能夠自由設計

  5. 狀態

    1. RN體系中明確提出的概念

    2. 傳統設計方案中通常使用內部屬性來表示

傳統設計思路

按照原來設計組件的方法論,一個UI組件對外應該具備屬性、事件、接口,對內具備內部屬性,內部接口。

  1. 屬性就像一份配置文件,描述了組件應該具備的功能、外觀或者初始狀態。

  2. 事件是組件在工做工程中,當知足某種條件的時候觸發的回調函數

  3. 接口是組件對象的方法,可讓組件去執行某個任務

在原來的設計理念中,並無提出組件狀態的概念,可是其也是一直存在的,一般是使用組件私有屬性來存儲。

好比,你設計一個按鈕,那麼他可能有正常狀態,禁用狀態,那麼咱們會設計一個屬性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');

RN設計思路

上面的示例中,表示了一個傳統UI組件的設計思路,_disable就是這個button組件的關鍵狀態,它直接影響了組件的表現和行爲。

而react架構直接把組件狀態提高到了一個新的高度,主要有如下幾點:

  1. 使用固定的接口來聲明組件狀態和狀態默認值

  2. 使用固定的接口來得到和改變組件狀態的值

  3. 狀態的改變必定會改變組件的表現,會致使組件的從新渲染

前兩項都不是問題,由於咱們原來也得有這些東西,只不過寫法發生了變化,關鍵是最後一項。這裏說的不是問題,指的是思路上比較容易接受。這種固定寫法,問題也很明顯,由於要想把一個狀態從RN狀態體系拿進拿出,會產生必定的工做成本,非常不爽。

我一直在思索,組件狀態的變化必定要致使view的變化嗎?

答案確定是no,由於有些狀態僅僅影響組件的行爲,並不影響表現。好比說,我賦予按鈕一個新功能,它能夠提交某個表單的數據,也就是須要一個新的狀態formName,他就不影響表現,隻影響行爲。

考慮到性能的極致,咱們就只能把這種狀態放到RN的狀態體系以外,做爲對象的私有屬性存在。

RN號稱diff算法性能很高,但也不是0損耗,若是對RN的渲染理解很透徹,你固然也能夠不這樣設計,可是我這裏仍是傾向於保守一些,不然後期的調整也是有工做量的,由於定義、初始化、取值、改值這些操做代碼都不同。寫到這裏我忽然想到,若是能夠,咱們能夠經過某種方法方便的修改某個狀態是否影響表現,不用改其它代碼的話,那麼咱們設計狀態的時候就不用區分了,就能讓咱們更關注設計自己。

結論

說道這裏,基本能夠理清思路了。

組件按照傳統方式設計,該怎麼設計就怎麼設計,在設計原來組件內部屬性的時候,多考慮一步,哪些內部屬性的改變是影響表現的,哪些內部屬性是不影響表現的。將影響表現的放入到RN狀態體系中,將不影響表現的,放入內部屬性中。便可。

tips

  1. 耦合性很強的父子組件,建議將狀態統一放到父組件中,子組件中不要放狀態了,不管是狀態的跨組件共享,仍是對view渲染的觸發都很方便。除非你很肯定某個狀態只子組件內部使用,一般這種狀況後邊可能也會發生變化。

  2. 如下問題能夠幫助識別是不是state,摘自官網

    1. 是不是從父級經過 props 傳入的?若是是,可能不是 state 。

    2. 是否會隨着時間改變?若是不是,可能不是 state 。

    3. 能根據組件中其它 state 數據或者 props 計算出來嗎?若是是,就不是 state 。

  3. 根據state的特色進行識別,加入到上一條

    1. 屬性的改變會影響到view的變化就多是state

  4. 參考地址

    1. https://facebook.github.io/react/docs/thinking-in-react.html

    2. http://wiki.jikexueyuan.com/project/react/thinking-in-react.html

相關文章
相關標籤/搜索