摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。并且這個任務(wù)是最后被啟動的那個。如果之前已經(jīng)有一個任務(wù)在執(zhí)行,那之前的這個任務(wù)會自動被取消。如果我們允許多個實例同時啟動?;蛘咧钡奖涣?,如果是這種情況,將在中拋出一個錯誤。完整項目代碼地址
上回說到使用Redux進行狀態(tài)管理,這次我們使用Redux-saga 管理 Redux 應(yīng)用異步操作React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時間了,現(xiàn)在就開始用 React+Redux 進行實戰(zhàn)!
React 實踐項目 (一)
React 實踐項目 (二)
React 實踐項目 (三)
export const auth = (state = initialState, action = {}) => { switch (action.type) { case LOGIN_USER: return state.merge({ "user": action.data, "error": null, "token": null, }); case LOGIN_USER_SUCCESS: return state.merge({ "token": action.data, "error": null }); case LOGIN_USER_FAILURE: return state.merge({ "token": null, "error": action.data }); default: return state } };
Sagas 監(jiān)聽發(fā)起的 action,然后決定基于這個 action 來做什么:是發(fā)起一個異步調(diào)用(比如一個 Ajax 請求),還是發(fā)起其他的 action 到 Store,甚至是調(diào)用其他的 Sagas。
具體到這個登陸功能就是我們在登陸彈窗點擊登陸時會發(fā)出一個 LOGIN_USER action,Sagas 監(jiān)聽到 LOGIN_USER action,發(fā)起一個 Ajax 請求到后臺,根據(jù)結(jié)果決定發(fā)起 LOGIN_USER_SUCCESS action 還是LOGIN_USER_FAILURE action
接下來,我們來實現(xiàn)這個流程
創(chuàng)建 Saga middleware 連接至 Redux store
在 package.json 中添加 redux-saga 依賴
"redux-saga": "^0.15.4"
修改 src/redux/store/store.js
/** * Created by Yuicon on 2017/6/27. */ import {createStore, applyMiddleware } from "redux"; import createSagaMiddleware from "redux-saga" import reducer from "../reducer/reducer"; import rootSaga from "../sagas/sagas"; const sagaMiddleware = createSagaMiddleware(); const store = createStore( reducer, applyMiddleware(sagaMiddleware) ); sagaMiddleware.run(rootSaga); export default store;
Redux-saga 使用 Generator 函數(shù)實現(xiàn)
監(jiān)聽 action
創(chuàng)建 src/redux/sagas/sagas.js
/** * Created by Yuicon on 2017/6/28. */ import { takeLatest } from "redux-saga/effects"; import {registerUserAsync, loginUserAsync} from "./users"; import {REGISTER_USER, LOGIN_USER} from "../action/users"; export default function* rootSaga() { yield [ takeLatest(REGISTER_USER, registerUserAsync), takeLatest(LOGIN_USER, loginUserAsync) ]; }
我們可以看到在 rootSaga 中監(jiān)聽了兩個 action 登陸和注冊 。
在上面的例子中,takeLatest 只允許執(zhí)行一個 loginUserAsync 任務(wù)。并且這個任務(wù)是最后被啟動的那個。 如果之前已經(jīng)有一個任務(wù)在執(zhí)行,那之前的這個任務(wù)會自動被取消。
如果我們允許多個 loginUserAsync 實例同時啟動。在某個特定時刻,我們可以啟動一個新 loginUserAsync 任務(wù), 盡管之前還有一個或多個 loginUserAsync 尚未結(jié)束。我們可以使用 takeEvery 輔助函數(shù)。
發(fā)起一個 Ajax 請求
獲取 Store state 上的數(shù)據(jù)
selectors.js
/** * Created by Yuicon on 2017/6/28. */ export const getAuth = state => state.auth;
api
api.js
/** * Created by Yuicon on 2017/7/4. * https://github.com/Yuicon */ /** * 這是我自己的后臺服務(wù)器,用 Java 實現(xiàn) * 項目地址:https://github.com/DigAg/digag-server * 文檔:http://139.224.135.86:8080/swagger-ui.html#/ */ const getURL = (url) => `http://139.224.135.86:8080/${url}`; export const login = (user) => { return fetch(getURL("auth/login"), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(user) }).then(response => response.json()) .then(json => { return json; }) .catch(ex => console.log("parsing failed", ex)); };
創(chuàng)建 src/redux/sagas/users.js
/** * Created by Yuicon on 2017/6/30. */ import {select, put, call} from "redux-saga/effects"; import {getAuth, getUsers} from "./selectors"; import {loginSuccessAction, loginFailureAction, registerSuccessAction, registerFailureAction} from "../action/users"; import {login, register} from "./api"; import "whatwg-fetch"; export function* loginUserAsync() { // 獲取Store state 上的數(shù)據(jù) const auth = yield select(getAuth); const user = auth.get("user"); // 發(fā)起 ajax 請求 const json = yield call(login.bind(this, user), "login"); if (json.success) { localStorage.setItem("token", json.data); // 發(fā)起 loginSuccessAction yield put(loginSuccessAction(json.data)); } else { // 發(fā)起 loginFailureAction yield put(loginFailureAction(json.error)); } }
select(selector, ...args) 用于獲取Store state 上的數(shù)據(jù)
put(action) 發(fā)起一個 action 到 Store
call(fn, ...args) 調(diào)用 fn 函數(shù)并以 args 為參數(shù),如果結(jié)果是一個 Promise,middleware 會暫停直到這個 Promise 被 resolve,resolve 后 Generator 會繼續(xù)執(zhí)行。 或者直到 Promise 被 reject 了,如果是這種情況,將在 Generator 中拋出一個錯誤。
Redux-saga 詳細api文檔
結(jié)語
我在工作時用的是 Redux-Thunk, Redux-Thunk 相對來說更容易實現(xiàn)和維護。但是對于復(fù)雜的操作,尤其是面對復(fù)雜異步操作時,Redux-saga 更有優(yōu)勢。到此我們完成了一個 Redux-saga 的入門教程,Redux-saga 還有很多奇妙的地方,大家可以自行探索。
完整項目代碼地址
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/88321.html
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。惟一改變的辦法是觸發(fā),一個描述發(fā)生什么的對象。對對象的任何修改或添加刪除操作都會返回一個新的對象。從導(dǎo)入需要的類型初始化狀態(tài)就是一個純函數(shù),接收舊的和,返回新的。 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時間了,現(xiàn)在就開始用 React+Redux 進行實戰(zhàn)! Re...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。為了檢驗效果當然是選擇部署到服務(wù)器。下篇文章將會介紹利用的鏡像部署應(yīng)用。完整項目代碼地址 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時間了,現(xiàn)在就開始用 React+Redux 進行實戰(zhàn)! 上回說到使用Redux-saga 管理 Redux 應(yīng)用異步操作,應(yīng)用還是只有...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應(yīng)一個文件??偨Y(jié)上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
摘要:下面會從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個子頁面對應(yīng)一個文件??偨Y(jié)上面就是最早版本的源碼,很簡潔的使用了等其目的也很簡單簡化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
閱讀 3179·2021-09-10 10:51
閱讀 3361·2021-08-31 09:38
閱讀 1655·2019-08-30 15:54
閱讀 3142·2019-08-29 17:22
閱讀 3222·2019-08-26 13:53
閱讀 1973·2019-08-26 11:59
閱讀 3292·2019-08-26 11:37
閱讀 3319·2019-08-26 10:47