- React組件訪問服務器的方式
- Redux架構下訪問服務器的方式
一、React組件訪問服務器
-
代理功能訪問API
- React組件訪問服務器的生命週期
以顯示天氣預報爲示例:
- 通過服務器API獲得天氣情況數據
- 展示天氣情況數據
分兩個步驟完成:
(1)在裝載過程中,因爲weather組件並沒有獲得服務器結果,就不顯示結果。或者顯示一個’正在裝載‘之類的提示信息,但weather組件這時候要發出對服務器的請求。
(2)獲取到天氣數據之後,顯示出來
在裝載過程中,通常我們在組件的componentDidMount函數中做請求服務器的事情。
- React組件訪問服務器的優缺點
將狀態放在組件中不是很好的選擇,尤其是當組件變得複雜龐大了之後。Redux是用來幫助管理應用狀態的,應該儘量把狀態存放在Redux Store的狀態中,而不是放在React組件中。
二、Redux訪問服務器
-
Redux-thunk中間件
使用Redux訪問服務器,同樣要解決的是異步問題。
Redux的單向數據流是同步操作,驅動Redux流程的是action對象,每一個action對象被派發到Store上之後,同步的被分配給所有的reducer函數,每個reducer都是純函數,純函數不產生任何副作用,自然是完成數據操作之後立刻同步返回,reducer返回的結果又被同步的拿去更新Store上的狀態數據,更新狀態數據的操作會立即被同步給監聽Store狀態改變的函數,從而引發作爲視圖的React組件更新過程。
在這個過程中,Redux-chunk可以作爲Redux中異步操作的方法之一。
按照Redux-chunk的想法,在Redux的單向數據流中,在action對象被reducer函數處理之前,是插入異步功能的時機。
在Redux架構下,一個action對象在通過store.dispatch派發,在調用reducer函數之前,會先經過一箇中間件環節,這就是產生異步操作的時機,實際上Redux-chunk提供的就是一個Redux中間件,我們需要在創建store時用上這個中間件。 -
異步action對象
當我們想要讓Redux幫忙處理一個異步操作的時候,代碼一樣也要派發一個action對象,畢竟Redux單向數據流就是由action對象驅動的,但是這個引發異步操作的action對象比較特殊,我們叫他們’異步action對象‘。
有了redux-chunk中間件之後,這些action對象根本沒有機會觸及到reducer函數,在中間件一層就被redux-chunk截獲。
redux-chunk的工作是檢查action對象是不是函數,如果不是函數就放行,完成普通action對象的生命週期,而如果發現action對象是函數,那就執行這個函數,並把Store的dispatch函數和getState函數作爲參數傳遞到函數中去,處理過程到此爲止,不會讓這個異步action對象繼續往前派發到reducer函數。 -
異步操作的模式
一個訪問服務器的action,至少要涉及3個action類型:- 表示異步操作已經開始的action類型,例如:表示一個請求天氣信息的API請求已經發送給服務器的狀態;
- 表是異步操作成功的action類型,請求天氣信息的API調用獲得了正確的結果,就會引發這種類型的action;
- 表示異步操作失敗的action類型,請求天氣信息的API調用任何一個環節出了錯誤,無論是網絡錯誤、本地代理服務錯誤還是遠程服務器返回的結果錯誤,都會引發這個類型的action。
當這三種類型的action對象被派發時,會讓React組件進入各自不同的三種狀態,如: - 異步操作正在進行中
- 異步操作已經成功完成
- 任務操作已經失敗
- 異步操作的終止
拿天氣預報的例子舉例:
從用戶角度出發,當連續選擇城市的時候,總是希望顯示最後一次選中的城市信息,也就是說,一個更好的辦法是在發出API請求的時候,將之前的API請求全部終止作廢,這樣就保證了獲得的有效結果絕對是用戶的最後一次選擇結果。
三、如何挑選異步操作方式
-
在Redux的單向數據流中,什麼時機插入異步操作?
Redux的數據流轉完全靠action來驅動,對於redux-chunk,切入異步操作的時機是在中間件中,但這並不是唯一的位置。
通過定製化Store Enhancer,可以在action派發路徑上任何一個位置插入異步操作,甚至作爲純函數的reducer都可以幫助實現異步操作。異步操作本身就是一種副作用,reducer的執行過程當然不應該產生異步操作,但是reducer函數的返回值卻可以包含對異步操作的’指示‘,也就是說,reducer返回的結果可以用純數據的方式表示需要發起一個對服務器資源的訪問,由reducer調用者去真正執行這個訪問服務器資源的操作,這樣不違背reducer是一個純函數的原則。 -
對應庫的大小如何?
幾KB-幾十KB -
學習曲線是不是太陡?
如果一個應用只有一個簡單的API請求,使用redux-thunk能解決的話就使用redux-thunk。 - 是否會和其他的Redux庫衝突?
可能會發生衝突,使用任何一個庫在Redux中實現異步操作,都需要多方面的考慮。
四、利用Promise實現異步操作
對於Promise在Redux庫中如何實現,相關的庫也很多,但是都很簡單,用一個Redux中間件就可以實現:
- redux-promise
- redux-promises
- redux-simple-promise
- redux-promise-middleware