JavaScript狀態機的理解

##有限狀態自動機,簡稱狀態機,是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。

React和React Native的狀態

##有限狀態機(Finite-state machine)是一個非常有用的模型,可以模擬世界上大部分事物。

簡單說,它有三個典型特征:

1:事物包含的狀態總數(state)是有限的。

2:任一時刻,事物僅且只能處于一種狀態之中。

3:某種事件驅動下,可以導致事物從一種狀態切換到另一種狀態。

在維基百科中稱:有限狀態機FSM是設計和實現事件驅動程序內復雜行為組織原則的有力工具。

傳統的MVC設計中

它對JavaScript的意義在于,很多對象可以寫成有限狀態機。

有限狀態機的寫法,邏輯清晰,表達力強,有利于封裝事件。一個對象的狀態越多、發生的事件越多,就越適合采用有限狀態機的寫法。

另外,JavaScript語言是一種異步操作特別多的語言,常用的解決方法是指定回調函數,但這樣會造成代碼結構混亂、難以測試和除錯等問題。有限狀態機提供了更好的辦法:把異步操作與對象的狀態改變掛鉤,當異步操作結束的時候,發生相應的狀態改變,由此再觸發其他操作。這要比回調函數、事件監聽、發布/訂閱等解決方案,在邏輯上更合理,更易于降低代碼的復雜度。

有限狀態機非常重要的一點就是講用戶的操作行為,也就是組件的事件響應與組件的表現分離開來.通過建立一個有限狀態機的組件時,我們完全不關心用戶的操作行為具體做了什么,這時組件可能會有幾種狀態對應不同的表現形式,而用戶觸發的事件僅僅是切換了模型的狀態.至于每個狀態的具體表現和行為,我們完全可以單獨定義,也就說這時一種行為和響應上的解耦.

當用戶的操作發生變化的時候,我們僅僅需要改變根數據,也就是state源.而不需要像以往的MVC設計中,當行為發生時,我們既需要在C層改變Model,同時還要操作View進行更新.在復雜的交互場景中代碼尤其臃腫難以維護.狀態機的設計思路,很好的解決了這個問題,用戶操作行為僅僅與修改數據關聯,而與其他無關.

React框架中將UI簡單的看作有點狀態機的組件集合。將UI看作包含了各種各樣的狀態的組件,并在各種狀態間切換,很容易保持UI的一致性。在React中,你只要改變組件的狀態,就會自動重新渲染UI,React會在最有高效的方式下更新虛擬DOM。

通過調用setState(data, callback)方法,改變狀態,就會觸發React更新UI。大部分情況下,我們不需要提供callback函數。React會自動的幫我們更新UI。

后面在好好看看這個callback的功能和調用時機。

使用React組件時,免不了就需要跟props,state這兩個屬性打交道.

props是從父組件或者組件創建時外部傳遞來的,大多數組件在創建時就可以使用各種參數來進行定制,這些定制的參數就props,props是在父組件中指定,而且一經指定,在被指定的組件的生命周期中則不再改變

state也是用來控制描述一個組件的,對于需要改變的數據,我們需要使用state。

那么什么樣的組件該有state呢?

大部分的組件應該從props屬性中獲取數據并渲染。但有的時候組件得相應用戶輸入或者交互響應,或同服務器交互,這些情況下會用到state。React的官方說法是:盡可能的保持你的組件無狀態化(個人的理解就是更好的貼合單向數據流這一理念)。為了實現這個目標,得保持你的狀態同業務邏輯分離,并減少冗余信息,盡可能保持組件的單一職責。

state應該包含什么樣的數據

UI交互,服務器交互,會導致改變的數據。

state不應包含什么樣的數據

1.計算過的數據

2.組件

3.從props復制的數據

React官方推薦的一種模式就是:構建幾個無狀態的組件用來渲染數據,在這些之上構建一個有狀態的組件同用戶和服務交互,數據通過props傳遞給無狀態的組件。

React的作者認為,組件應該同關注分離,而不是同模板和展現邏輯分離。結構化標記和生成結構化標記的代碼是緊密關聯的,此外,展現邏輯一般都很復雜,使用模板語言會使展現變得笨重。

React解決這個問題的方式就是:直接通過JavaScript代碼生成虛擬Dom和組件樹,這樣的話,你就可以使用JavaScript富豐的表達力去構建UI。為了使這個過程變得更簡單,React創建了類似HTML的語法去構建節點樹,也就是JSX了。這樣可以更方便的創建模板化的組件,方便代碼復用.

如果一個組件的數據都是不變的,這意味著UI顯示部分也是不變的,那么它就不應當成為一個單獨的RN組件,因為單獨的RN組件肯定是數據會被改變的.

對于無狀態的RN組件來說,會被改變的數據來自于它的props(屬性),而對于有狀態的RN組件來說,會被改變的數據不僅來自于它的props,還來自于它的state(狀態機變量).盡可能的讓自定義的組件成為無狀態的RN組件,以為者盡可能的讓自定義的RN組件沒有狀態機變量.

一個好的設計思路是:

創建多個只負責渲染的無狀態的RN組件,將他們封裝在一個有狀態的RN組件中,并把這個有狀態的RN組件的狀態機變量的值通過props的形式傳遞給無狀態的RN組件中.在這種設計思路下,有狀態的RN組件封裝了UI的交互邏輯,而無狀態的RN組件只負責渲染UI界面.

但是狀態機變量的改變會導致RN組件的重新渲染,所以提高RN應用程序性能的一種方式就是努力減少狀態機變量的數目.

在RN組件的render函數中,在正確的位置引用狀態機變量.

組件之間的通信:

父組件向子組件傳遞消息,數據通過回調父組件傳遞給自己的回調函數來實現.回調函數于父組件設定,被保存在子組件的某個屬性中,等待需要向父組件傳遞消息的時候調用.

除了setState函數意外,RN還提供了replaceState函數與forceUpdate函數

狀態機的優點:

1)有限狀態機是定義組件的一種好用的設計模式,能夠讓組件的代碼看起來更加清晰,而且易于理解;

2)有限狀態機這種模式適合有明顯狀態特點的組件;

3)本文所舉的例子不夠貼近實際項目,近期會看看自己做過的項目中有哪些適合用狀態機模式來重寫的模塊,到時候再寫博客來與大家分享。

有一個異步操作(light.fadeOut)。如果不希望狀態立即改變,就要讓回調函數返回StateMachine.ASYNC,表示狀態暫時不改變;等到異步操作結束,再調用transition方法,使得狀態發生改變。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,087評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,207評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,603評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,813評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,364評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,110評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,305評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,532評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,033評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,268評論 2 375

推薦閱讀更多精彩內容