摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。并且這個(gè)任務(wù)是最后被啟動(dòng)的那個(gè)。如果之前已經(jīng)有一個(gè)任務(wù)在執(zhí)行,那之前的這個(gè)任務(wù)會(huì)自動(dòng)被取消。如果我們?cè)试S多個(gè)實(shí)例同時(shí)啟動(dòng)。或者直到被了,如果是這種情況,將在中拋出一個(gè)錯(cuò)誤。完整項(xiàng)目代碼地址
上回說到使用Redux進(jìn)行狀態(tài)管理,這次我們使用Redux-saga 管理 Redux 應(yīng)用異步操作React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Redux 進(jìn)行實(shí)戰(zhàn)!
React 實(shí)踐項(xiàng)目 (一)
React 實(shí)踐項(xiàng)目 (二)
React 實(shí)踐項(xiàng)目 (三)
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,然后決定基于這個(gè) action 來做什么:是發(fā)起一個(gè)異步調(diào)用(比如一個(gè) Ajax 請(qǐng)求),還是發(fā)起其他的 action 到 Store,甚至是調(diào)用其他的 Sagas。
具體到這個(gè)登陸功能就是我們?cè)诘顷憦棿包c(diǎn)擊登陸時(shí)會(huì)發(fā)出一個(gè) LOGIN_USER action,Sagas 監(jiān)聽到 LOGIN_USER action,發(fā)起一個(gè) Ajax 請(qǐng)求到后臺(tái),根據(jù)結(jié)果決定發(fā)起 LOGIN_USER_SUCCESS action 還是LOGIN_USER_FAILURE action
接下來,我們來實(shí)現(xiàn)這個(gè)流程
創(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ù)實(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)聽了兩個(gè) action 登陸和注冊(cè) 。
在上面的例子中,takeLatest 只允許執(zhí)行一個(gè) loginUserAsync 任務(wù)。并且這個(gè)任務(wù)是最后被啟動(dòng)的那個(gè)。 如果之前已經(jīng)有一個(gè)任務(wù)在執(zhí)行,那之前的這個(gè)任務(wù)會(huì)自動(dòng)被取消。
如果我們?cè)试S多個(gè) loginUserAsync 實(shí)例同時(shí)啟動(dòng)。在某個(gè)特定時(shí)刻,我們可以啟動(dòng)一個(gè)新 loginUserAsync 任務(wù), 盡管之前還有一個(gè)或多個(gè) loginUserAsync 尚未結(jié)束。我們可以使用 takeEvery 輔助函數(shù)。
發(fā)起一個(gè) Ajax 請(qǐng)求
獲取 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 */ /** * 這是我自己的后臺(tái)服務(wù)器,用 Java 實(shí)現(xiàn) * 項(xiàng)目地址: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 請(qǐng)求 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ā)起一個(gè) action 到 Store
call(fn, ...args) 調(diào)用 fn 函數(shù)并以 args 為參數(shù),如果結(jié)果是一個(gè) Promise,middleware 會(huì)暫停直到這個(gè) Promise 被 resolve,resolve 后 Generator 會(huì)繼續(xù)執(zhí)行。 或者直到 Promise 被 reject 了,如果是這種情況,將在 Generator 中拋出一個(gè)錯(cuò)誤。
Redux-saga 詳細(xì)api文檔
結(jié)語
我在工作時(shí)用的是 Redux-Thunk, Redux-Thunk 相對(duì)來說更容易實(shí)現(xiàn)和維護(hù)。但是對(duì)于復(fù)雜的操作,尤其是面對(duì)復(fù)雜異步操作時(shí),Redux-saga 更有優(yōu)勢(shì)。到此我們完成了一個(gè) Redux-saga 的入門教程,Redux-saga 還有很多奇妙的地方,大家可以自行探索。
完整項(xiàng)目代碼地址
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/88321.html
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。惟一改變的辦法是觸發(fā),一個(gè)描述發(fā)生什么的對(duì)象。對(duì)對(duì)象的任何修改或添加刪除操作都會(huì)返回一個(gè)新的對(duì)象。從導(dǎo)入需要的類型初始化狀態(tài)就是一個(gè)純函數(shù),接收舊的和,返回新的。 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Redux 進(jìn)行實(shí)戰(zhàn)! Re...
摘要:在上已經(jīng)有接近的數(shù)了,是目前最熱門的前端框架。為了檢驗(yàn)效果當(dāng)然是選擇部署到服務(wù)器。下篇文章將會(huì)介紹利用的鏡像部署應(yīng)用。完整項(xiàng)目代碼地址 React在Github上已經(jīng)有接近70000的 star 數(shù)了,是目前最熱門的前端框架。而我學(xué)習(xí)React也有一段時(shí)間了,現(xiàn)在就開始用 React+Redux 進(jìn)行實(shí)戰(zhàn)! 上回說到使用Redux-saga 管理 Redux 應(yīng)用異步操作,應(yīng)用還是只有...
摘要:下面會(huì)從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個(gè)子頁面對(duì)應(yīng)一個(gè)文件。總結(jié)上面就是最早版本的源碼,很簡(jiǎn)潔的使用了等其目的也很簡(jiǎn)單簡(jiǎn)化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯(cuò)的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
摘要:下面會(huì)從淺到深,淡淡在閱讀源碼過程中自己的理解。分拆子頁面后,每一個(gè)子頁面對(duì)應(yīng)一個(gè)文件。總結(jié)上面就是最早版本的源碼,很簡(jiǎn)潔的使用了等其目的也很簡(jiǎn)單簡(jiǎn)化相關(guān)生態(tài)的繁瑣邏輯參考源碼地址 ??dva的思想還是很不錯(cuò)的,大大提升了開發(fā)效率,dva集成了Redux以及Redux的中間件Redux-saga,以及React-router等等。得益于Redux的狀態(tài)管理,以及Redux-saga中...
閱讀 3170·2021-09-10 10:51
閱讀 3351·2021-08-31 09:38
閱讀 1639·2019-08-30 15:54
閱讀 3129·2019-08-29 17:22
閱讀 3214·2019-08-26 13:53
閱讀 1960·2019-08-26 11:59
閱讀 3283·2019-08-26 11:37
閱讀 3308·2019-08-26 10:47