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