摘要:目的是為了解決在重用的時候,持久和方法重用的問題。換句話說你不用擔心把組件寫成模式不好重用,如果你需要傳統的方式使用,一下即可。
這篇文章所述的思想最終進化成了一個簡單的狀態管理模式,稱React StateUp Pattern,詳細介紹請參閱:https://segmentfault.com/a/11...
寫了一個非常簡單的實驗性Pattern,暫且稱為PurifiedComponent。目的是為了解決React Component在重用的時候,state持久和方法重用的問題。
React組件和state的生命周期不一致,即使是在一個對話框內,也可能因為折疊或者平移,一些組件消失但是他們的state還需要持久;這種情況下在this.state內存放狀態并不能解決問題,因為如果這個組件在渲染時消失了,它的state也沒了;
React官方的說法是應該把state寫到相關組件的共同祖先上去,這一點在實現邏輯上本身沒有問題,有問題的地方是重用很不方便;很多view state,例如和輸入框配合的校驗函數或者出錯信息,他們本身就應該是和組件一起使用的,離開組件去多帶帶維護沒有意義;
解決這個問題的思路是,把組件需要的view state獨立構建對象;持久化state的責任,托管到父組件去,但是對組件操作的責任,仍然留在子組件內,換句話說,子組件和它的state是由父組件bind在一起的。
class PurifiedComponent extends React.PureComponent { setState(props) { let { state, name, setState } = this.props setState({ [name] : Object.assign(new state.constructor(), state, props) }) } } class Impure extends React.Component { constructor(props) { super() this.state = { state: new props.component.State() } } render() { let Component = this.props.component return} }
上面的兩個class是基礎類;PurifiedComponent在React.PureComponent基礎上實現了一個setState方法。
使用方式看下面的例子,Child1是一個獨立PurifiedComponent的例子,Composite是組合的例子;
繼承自PurifiedComponent的類需要提供一個靜態類變量State,它是一個class;這個類是用于描述狀態的類,即所謂的view state;它也應該具有行為,尤其是那些計算computed的方法,對父組件來說可以直接訪問;
PurifiedComponent不在類結構內維護state,即不使用this.state;創建和保存它的state是它的父容器的職責;父容器可以通過new Child1.State()創建這個state;這是第一個約定;
第二個約定是,這些類需要有三個props:
state,從外部傳入的state;
name,state在父容器組件的state內的property name;
setState,父容器的setState方法;
有了這三者后,子組件就可以做stateful的工作,用傳入的state和setState工作;name原則來說不是邏輯需要的,但可以結合PureComponent避免不必要的刷新。
class Child1 extends PurifiedComponent { static State = class State { constructor() { this.label = "" } } render() { let {state, name} = this.props console.log(`render ${name}`) return () } }
Composite是一個組合,目前沒有設計使用數組組合的方式,只看看用Property Name來組合的辦法,這個Composite和它的子組件一樣沒有使用自己的this.state,這顯示了這種Pattern是可以自下而上組成樹的;
Composite的構造函數里有一個this.ssb,它表示的是bound函數,之所以在對象上創建是為了保持它的引用穩定,這樣在向child傳遞三個參數時,setState和name都是恒定的,只有第一個state變化時子組件會重新渲染;這是我們需要的特性;
class Composite extends PurifiedComponent { static State = class State { constructor() { this.child1 = new Child1.State() this.child2 = new Child1.State() } } constructor() { super() this.ssb = this.setState.bind(this) } render() { return () } } class App extends Component { render() { return} } export default App
最后的Impure是一鍵攔截這種層層向上提升state holder的行為,它可以作為一個stateful的組件,用它的this.state來裝載所有內含的PurifiedComponent構成的樹。換句話說你不用擔心把組件寫成Purified模式不好重用,如果你需要傳統的方式使用,Impure一下即可。
上述代碼雖然簡單但是可以工作,我會在生產環境中嘗試一下。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88168.html
摘要:一般這種情況會在類的構造函數內創建一個屬性,引用或詞法域的,但后面會看到我們有更好的辦法,避免這種手工代碼。 換句話說,StateUp模式把面向對象的設計方法應用到了狀態對象的管理上,在遵循React的組件化機制和基于props實現組件通訊方式的前提之下做到了這一點。 ---- 少婦白潔 閱讀本文之前,請確定你讀過React的官方文檔中關于Lifting State Up的論述: ht...
摘要:本文用于闡述模式的算法和數學背景,以及解釋了它為什么是里最完美的狀態管理實現。歡迎大家討論和發表意見。 本文用于闡述StateUp模式的算法和數學背景,以及解釋了它為什么是React里最完美的狀態管理實現。 關于StateUp模式請參閱:https://segmentfault.com/a/11... P-State, V-State 如果要做組件的態封裝,從組件內部看,存在兩種不同的...
摘要:匿名函數是我們喜歡的一個重要原因,也是,它們分別消除了很多代碼細節上需要命名變量名或函數名的需要。這個匿名函數內,有更多的操作,根據的結果針對目錄和文件做了不同處理,而且有遞歸。 能和微博上的 @響馬 (fibjs作者)掰扯這個問題是我的榮幸。 事情緣起于知乎上的一個熱貼,諸神都發表了意見: https://www.zhihu.com/questio... 這一篇不是要說明白什么是as...
摘要:的科學定義是或者,它的標志性原語是。能解決一類對語言的實現來說特別無力的狀態機模型流程即狀態。容易實現是需要和的一個重要原因。 前面寫了一篇,寫的很粗,這篇講講一些細節。實際上Fiber/Coroutine vs Async/Await之爭不是一個簡單的continuation如何實現的問題,而是兩個完全不同的problem和solution domain。 Event Model 我...
摘要:我們已經回答了的構造函數和原型都是誰的問題,現在牽扯出來一個,我們繼續檢查的構造函數是全局對象上屬性叫的對象的原型是個匿名函數,按照關于構造函數的約定,它應該是構造函數的屬性我們給這個對象起個名字,叫。 我不確定JavaScript語言是否應該被稱為Object-Oriented,因為Object Oriented是一組語言特性、編程模式、和設計與工程方法的籠統稱謂,沒有一個詳盡和大家...
閱讀 3072·2021-11-25 09:43
閱讀 2251·2021-09-07 10:28
閱讀 3543·2021-08-11 11:14
閱讀 2777·2019-08-30 13:49
閱讀 3544·2019-08-29 18:41
閱讀 1163·2019-08-29 11:26
閱讀 1976·2019-08-26 13:23
閱讀 3372·2019-08-26 10:43