React全家桶-06-redux-saga的使用

219 阅读2分钟

redux-thunkreduxreducer从接收一个对象,扩展为函数,但是对于更大型的项目,对于副作用的处理上,redux-saga更具优势,看这个名字起得,气势上这一块就拿捏的死死的,除了redux-observable还有谁~!(但是rxjs学习曲线堪称陡峭,笔者后续会学习更新)。代码依然是延用上期全家桶04-react-redux中使用redux-thunk做的模拟登陆的操作例子,这里会redux-saga去实现这个功能。

1.redux-saga:

redux-saga 是⼀个⽤于管理应⽤程序 Side Effffect(副作⽤,例如异步获取数据,访问浏览器缓存等)library,它的⽬标是让副作⽤管理更容易,执⾏更⾼效,测试更简单,在处理故障时更容易。redux-saga 使⽤了ES6Generator 功能,让异步的流程更易于读取,写⼊和测试。

🚀 目录结构如下:

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下面的logingenerator函数时用来调用api对象中的login方法的。
  • mySaga是将saga*login关联起来,然后导出mySaga; 🚀 详细流程如下:
  • saga.js里面一定要导出一个generator函数,里面通过使用takeEvery方法抓取指定的actionType后执行相应的方法,最好这个方法也是一个generator函数,然后得到相应的数据;
  • 之后把取来的数据(这里指的是result)结果再创建一个action通过put派发给storestore接收到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;