91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用redux怎么實現異步操作

發布時間:2021-06-11 17:53:55 來源:億速云 閱讀:2166 作者:Leah 欄目:web開發

使用redux怎么實現異步操作,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一、redux基礎

redux

  1. 通過 dispatch(action) -> 中間件 -> reducer處理數據 -> 改變store -> 使用subscribe()監聽store改變更新視圖 的方式管理狀態

  2. 將所有狀態存儲在一個store對象里面

  3. reducer為純函數,而異步操作由于結果的不確定性所以含有副作用,所以需要特殊處理

react-redux

  1. 容器組件,負責管理數據和業務邏輯,不負責UI呈現

  2. UI組件,提供UI呈現,無狀態即不使用this.state,狀態全部由this.props提供

  3. 由connect生成容器組件,每次store改變會調用connect,connect接收兩個參數: mapStateToProps, mapDispatchToProps

  4. mapStateToProps,將狀態映射到UI組件的props

  5. mapDispatchToProps,將dispatch方法映射到UI組件的props

  6. Provider組件,使用content API將store從頂層開始傳到每一層component供connect使用

二、redux處理異步的中間件

redux-thunk

  1. redux-thunk中間件允許action是一個方法

  2. 中間件收到action后會執行action方法并將結果提供給reducer

  3. action混亂導致不易維護

redux-saga

  1. saga會監聽action并基于這個action執行Effects操作

  2. Effects提供靈活的API,包括阻塞、非阻塞調用,取消、等待、race等操作

  3. 方便隔離并執行異步操作,并易于測試

三、redux-request-async-middleware

先從redux文檔中的異步action說起,每個接口調用需要dispatch三個同步action,分別是:

  1. 一種通知 reducer 請求開始的 action。對于這種 action,reducer 可能會切換一下 state 中的 isFetching 標記。以此來告訴 UI 來顯示加載界面。

  2. 一種通知 reducer 請求成功的 action。對于這種 action,reducer 可能會把接收到的新數據合并到 state 中,并重置 isFetching。UI 則會隱藏加載界面,并顯示接收到的數據。

  3. 一種通知 reducer 請求失敗的 action。對于這種 action,reducer 可能會重置 isFetching。另外,有些 reducer 會保存這些失敗信息,并在 UI 里顯示出來。

也就是一個接口發起是這樣的

dispatch(fetchPostsRequest(subject));
fetch(url).then(res => {
  dispatch(fetchPostsSuccess(subject, res));
}).catch(e => {
  dispatch(fetchPostsFailure(subject, e));
})

而我做的事情只是將這個操作封裝進中間件里,特殊的地方在于:

  1. 所有的異步請求共用這三個action

  2. 用subject來區分是哪一個請求

  3. 將所有的結果都放到store.requests里

中間件源碼

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
};
  1. 和redux-thunk一樣,將方法放進action里

  2. 中間件攔截FETCH_POSTS_REQUEST action,并進行異步處理

reducer源碼

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,
          }
        }
      );
    default:
      return state;
  }
}
  1. 將結果放入該subject對應下的response,如果錯誤的話將錯誤信息放入error當中

  2. isFetching表示當前的請求狀態

  3. 另外還加入了當前的狀態state和subject信息

將請求進行封裝

const request = (subject, model, next) => {
  _dispatch(fetchPostsRequest(subject, model, next));
  return true;
};
  1. 寫一個方法來發起FETCH_POSTS_REQUEST action

  2. 也就是說寫請求的時候不用再管action這東西了,直接調用request方法

將結果進行封裝

const getResponse = state =>
  state
  && state.response !== null
  && state.response;

const getLoading = (states = []) =>
  states.reduce((pre, cur) =>
    pre || (cur && cur.isFetching)
    , false)
  || false;
  1. 可以獲取結果和多個請求下loading的狀態

  2. 有更多的操作或者格式還可以繼續封裝,比如列表

使用方法redux-request-async-middleware

四、總結

  1. 使用了redux來進行狀態管理,而并不需要編寫redux那一套復雜邏輯,最大程度的減少異步操作的復雜度

  2. 適用于前端通過接口來處理和存儲數據的項目

  3. 接口由redux處理,而視圖組件由內部state來處理,而外部只暴露簡單的接口來進行操作,分離業務層和視圖層

  4. 對比react 16.3 new content API,redux的優勢在于熱插播的中間件和純函數reducer寫法

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

岱山县| 石嘴山市| 金平| 左云县| 松桃| 淮安市| 祥云县| 高淳县| 若尔盖县| 大丰市| 德州市| 凤庆县| 南投市| 库伦旗| 葫芦岛市| 剑阁县| 蒲城县| 宁夏| 五指山市| 阿瓦提县| 昌平区| 赤峰市| 香港| 循化| 普兰县| 象州县| 舞钢市| 亳州市| 扎兰屯市| 隆德县| 通江县| 肥东县| 台湾省| 蒙城县| 武隆县| 马尔康县| 阿坝| 乌拉特后旗| 乌拉特中旗| 浏阳市| 安塞县|