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

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的等價比較有時也並不簡單,好比包含類對象或函數。所以,若非有特殊需求,這類屬性作成一次性屬性便可。

說了這麼多,在實戰中,仍是要根據具體狀況靈活變通,關鍵是,知道的越多,辦法越多越好。

相關文章
相關標籤/搜索