redux-thunk
让redux
的reducer
从接收一个对象,扩展为函数
,但是对于更大型的项目,对于副作用
的处理上,redux-saga
更具优势,看这个名字起得,气势上这一块就拿捏的死死的,除了redux-observable
还有谁~!(但是rxjs
学习曲线堪称陡峭,笔者后续会学习更新)。代码依然是延用上期全家桶04-react-redux
中使用redux-thunk
做的模拟登陆的操作例子,这里会redux-saga
去实现这个功能。
1.redux-saga:
redux-saga
是⼀个⽤于管理应⽤程序 Side Effffect(副作⽤,例如异步获取数据,访问浏览器缓存等)
的 library
,它的⽬标是让副作⽤管理更容易,执⾏更⾼效,测试更简单,在处理故障时更容易。redux-saga
使⽤了ES6
的 Generator
功能,让异步的流程更易于读取,写⼊和测试。
🚀 目录结构如下:
redux
├─index.js
├─rootReducer.js
├─user
| ├─actionCreator.js
| ├─actionType.js
| └reducer.js
├─saga
| └saga.js
这里笔者这里就只更新改动的部分了,下面来看下redux-saga
的使用:
首先来看下saga/saga.js
:
import {put,takeEvery,call} from "redux-saga/effects"
//模拟登陆的api
const api = {
login(){
return new Promise((resolve,reject)=>{
setTimeout(()=>{
if(Math.random()>0.5){
resolve({id:24,name:"科比"})
}else{
reject("不存在这个球员")
}
},1000)
})
}
}
// Work saga
function* login(action){
try{
const result = yield call(api.login);
// 这里的put就相当于dispatch
yield put({type:"login",result})
}catch (error){
yield put({type:"loginError",message:error.message})
}
}
//将*login和saga关联起来
function* mySaga(){
// 这里的login指的是Work saga 的login
yield takeEvery("login_request",login)
}
export default mySaga;
- 创建
api
对象,其中login
函数返回一个promise
,有50%
的几率登录成功。 Work saga
下面的login
的generator
函数时用来调用api
对象中的login
方法的。mySaga
是将saga
和*login
关联起来,然后导出mySaga
; 🚀 详细流程如下:saga.js
里面一定要导出一个generator
函数,里面通过使用takeEvery
方法抓取指定的actionType
后执行相应的方法,最好这个方法也是一个generator
函数,然后得到相应的数据;- 之后把
取来的数据(这里指的是result)
结果再创建一个action
通过put
派发给store
,store
接收到action
后又给了reducer
,在reducer
中进行相应的处理。
🚀 然后来看下actionCreator.js
中的代码:
import {LOGIN} from "./actionType";
export const loginUser = () => {
return {
type:LOGIN
}
}
//redux-thunk可以让dispatch派发一个函数,这个函数接收dispatch为参数
// export const login = (dispatch)=>{
// setTimeout(()=>{
// const action = loginUser();
// dispatch(action);
// },1000)
// };
//for redux-saga 纯对象的action
export const login = ()=>{
return {
type:"login_request"
}
}
- 观察注释部分也能知道,
redux-saga
依然是返回的一个对象。
🚀 最后来看下redux/index.js
中的一些配置操作:
import {createStore} from "redux";
import {applyMiddleware} from "redux";
import logger from "redux-logger";
import {rootReducer} from "./rootReducer";
import createSagaMiddleware from "redux-saga";
import mySaga from "./saga/saga";
//1.创建中间件
const midSaga = createSagaMiddleware();
//2.通过applyMiddleware应用saga中间件
//创建store
// 🚀 安装完了中间件得通过applyMiddleware去使用中间件
// 🚀 通过combineReducers来组合多个reducer
const store = createStore(rootReducer,applyMiddleware(logger,midSaga));
//3.运行中间件
midSaga.run(mySaga);
export default store;