這篇文章帶給大家的內容是關於redux非同步操作的詳細介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
一、redux基礎
redux
透過dispatch(action) - > 中間件-> reducer處理資料-> 改變store -> 用subscribe()監聽store改變更新視圖的方式管理狀態
將所有狀態儲存在一個store物件裡面
reducer為純函數,而非同步運算由於結果的不確定性所以含有副作用,所以需要特殊處理
# #react-redux容器元件,負責管理資料與業務邏輯,不負責UI呈現
UI元件,提供UI呈現,無狀態即不使用this.state,狀態皆由this.props提供
由connect產生容器元件,每次store改變都會呼叫connect,connect接收兩個參數: mapStateToProps, mapDispatchToProps
mapStateToProps,將狀態映射到UI元件的props
mapDispatchToProps,將dispatch方法對應到UI元件的props
Provider元件,使用content API將store從頂層開始傳到每一層component供connect使用
二、redux處理非同步的中間件
#redux-thunkredux-thunk中間件允許action是一個方法
中間件收到action後會執行action方法並將結果提供給reducer
action混亂導致不易維護
redux-sagasaga會監聽action並基於這個action執行Effects操作
Effects提供靈活的API,包括阻塞、非阻塞調用,取消、等待、race等操作
方便隔離並執行非同步操作,並且易於測試
三、redux-request-async-middleware
先從redux文件中的非同步action說起,每個介面呼叫需要dispatch三個同步action,分別是:一種通知reducer 請求開始的action。對於這種 action,reducer 可能會切換一下 state 中的 isFetching 標記。以此告訴 UI 來顯示載入介面。
一種通知 reducer 請求成功的 action。對於這種 action,reducer 可能會將接收到的新資料合併到 state 中,並重置 isFetching。 UI 則會隱藏載入介面,並顯示接收到的資料。
一種通知 reducer 請求失敗的 action。對於這種 action,reducer 可能會重置 isFetching。另外,有些 reducer 會保存這些失敗訊息,並在 UI 裡顯示出來。
也就是一個介面發起是這樣的
dispatch(fetchPostsRequest(subject)); fetch(url).then(res => { dispatch(fetchPostsSuccess(subject, res)); }).catch(e => { dispatch(fetchPostsFailure(subject, e)); })只是將這個操作封裝進中間件裡,特殊的地方在於:
export const reduxRequest = store => next => action => { let result = next(action); let { type, subject, model } = action; let _next = action.next; if(type === FETCH_POSTS_REQUEST) { model().then(response => { _next && _next(response); store.dispatch(fetchPostsSuccess(subject, response)); }).catch(error => { console.error(error); store.dispatch(fetchPostsFailure(subject, error)); }); } return result };/
export const requests = (state = {}, action) => { switch (action.type) { case FETCH_POSTS_REQUEST: return assign({}, state, { [action.subject]: { isFetching: true, state: 'loading', subject: action.subject, response: null, error: null, } } ); case FETCH_POSTS_FAILURE: return assign({}, state, { [action.subject]: { isFetching: false, state: 'error', subject: action.subject, response: state[action.subject].response, error: action.error, } } ); case FETCH_POSTS_SUCCESS: return assign({}, state, { [action.subject]: { isFetching: false, state: 'success', subject: action.subject, response: action.response, } } ); case FETCH_POSTS_CLEAR: return assign({}, state, { [action.subject]: { isFetching: false, state: 'cleared', subject: null, response: null, error: null, } } ) return state; } }
const request = (subject, model, next) => { _dispatch(fetchPostsRequest(subject, model, next)); return true; };
const getResponse = state => state && state.response !== null && state.response; const getLoading = (states = []) => states.reduce((pre, cur) => pre || (cur && cur.isFetching) , false) || false;
以上是redux非同步操作的詳細介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!