Redux异步库_Redux-thunk_Redux-saga的使用方法及区别

Redux 异步:

通常情况下,action 只是一个普通的对象,不能包含异步操作,这导致了很多创建 action 的逻辑只能写在组件中,代码量较多也不便于复用,组件的业务逻辑也不清晰,使用中间件了之后,可以通过actionCreator异步编写action,这样代码就会拆分到 actionCreator 中,可维护性大大提高,可以方便于测试、复用,同时 actionCreator 还集成了异步操作中不同的 action 派发机制,减少编码过程中的代码量。

常见的异步库:

  • Redux-thunk
  • Redux-saga
  • Redux-effects
  • Redux-side-effects
  • Redux-loop
  • Redux-observable

基于Promise的异步库:

  • Redux-promise
  • Redux-promises
  • Redux-simple-promise
  • Redux-promise-middleware

最简单也是最常用的方法就是使用Redux Thunk middleware,这样就能用更为复杂或者异步的逻辑书写 action 创建函数。另一个被广泛使用的方法是Redux Saga,你可以用generator书写类同步代码,就像在 Redux 应用中使用 “后台线程” 或者 “守护进程”。

redux-thunk

在终端中执行下面的命令,安装 redux-thunk
yarn add redux-thunk

创建 store 的时候:

  • applyMiddleware 表示通知 redux 要用到一个异步的中间件;
  • createStore() 中第二个参数传入 applyMiddleware(thunk);
/* store.js */
import {createStore,applyMiddleware} from 'redux'
import reducer from './reducer'
import thunk from 'redux-thunk'

const store=createStore(reducer,applyMiddleware(thunk))

export default store;

reducer.js文件:

  • 根据 action 传过来的内容,对 store 中的数据做处理,并返回一个新的 state。
/* reducer.js */
const defaultState={ dataList:[] }

const reducer=(state=defaultState,action)=>{
    switch(action.type){
        case "ADD_LIST_DATA":
            return{
                dataList:list.concat(action.data)
            }
        default:
            return state;
    }
}

export default reducer;

connect.js文件中:

  • 默认情况下,mapDispatch 返回的方法中,dispatch 中的 action 只能是一个扁平的对象。
  • 使用redux-thunk中间件后,action可以是一个函数,在函数中进行异步操作,最终还是执行 dispatch。
/* connect.js */
import {connect} from 'react-redux'
import {loadListData} from './actionCreators'

const mapState=(state)=>{
    return{ dataList:state.dataList }
}

const mapDispatch=(dispatch)=>{
    return{
        loadData:(params)=>{
           dispatch(loadListData(params))
        }
    }
}

export default connect(mapState,mapDispatch)

actionCreators.js,请求接口,做异步操作

/* actionCreators.js */
const loadListData=(params)=>{
    return(dispatch)=>{
        axios.get('/datalist',params).then((rs)=>{
            dispatch({type:"ADD_LIST_DATA",data:rs.data})
        })
    }
}
export { loadListData }

redux-saga

redux-saga 用的是ES6的生成器函数generator功能,而不是async await

在终端中执行下面的命令,安装 redux-saga
yarn add redux-saga -S

创建 store 的时候:

  • 使用 createSagaMiddleware() 创建 sagaMiddleware。
  • mySaga 中是对数据做的异步处理,相当于thunk方式中 connect.js 和 actionCreators.js 中的操作。
/* store.js */
import {createStore,applyMiddleware} from 'redux'
import createSagaMiddleware from 'redux-saga'
import reducer from './reducer'
import mySaga from './sagas'

const sagaMiddleware = createSagaMiddleware()
const store = createStore(reducer,applyMiddleware(sagaMiddleware))
sagaMiddleware.run(mySaga)

export default store;

reducer.js文件:

  • 根据 action 传过来的内容,对 store 中的数据做处理,并返回一个新的 state。
  • 不管使用哪种异步库,reducer 里的操作都是一样的。
/* reducer.js */
const defaultState={ dataList:[] }

const reducer=(state=defaultState,action)=>{
    switch(action.type){
        case "ADD_LIST_DATA":
            return{
                dataList:list.concat(action.data)
            }
        default:
            return state;
    }
}

export default reducer;

connect.js文件中:

  • dispatch 中 action 仍旧是一个扁平的对象,它的 type 属性会去匹配 takeEvery() 方法里的第一个参数。
/* connect.js */
import {connect} from 'react-redux'

const mapState=(state)=>{
    return{ dataList:state.dataList }
}

const mapDispatch=(dispatch)=>{
    return{
        loadData:(params)=>{
           dispatch({type:"async_loadListData",...params})
        }
    }
}

export default connect(mapState,mapDispatch)

sagas.js文件:

  • takeEvery(),作用是将请求数据加到异步队列里,匹配 connect.js 中 dispatch 参数里的 type,匹配成功后,执行第二个参数,调用 put() 方法;
  • put(),它的参数是 action,相当于 thunk 里的 dispatch。将 action 发送到 reducer 中处理,改变 state;
/* sagas.js */
import { put, takeEvery } from 'redux-saga/effects'
//请求接口,做异步操作
const loadListData=(params)=> axios.get('/apilist/datalist',params)

function* load(params) {
  delete params.type;
  let rs = yield loadListData(params);
  yield put({type:"ADD_LIST_DATA",data:rs.data})
}

function* sagas(){
  yield takeEvery('async_loadListData',load)
} 

export default sagas;

redux-thunk 和 redux-saga 的区别

  • 上面的案例中,异步处理数据,thunk方式是在actionCreators.js 文件中,saga 方式在 sagas.js文件里;
  • redux-saga用的是generator语法。
  • 异步操作时,在connect.js文件里,thunk方式,action是个函数saga方式,action还是一个扁平的对象,会根据这个名字去找 takeEvery() 中的第一个参数,如果一致,则执行 takeEvery() 的第二个参数。
  • saga方式,在 store.js 文件中配置好后,里面可以正常写;thunk方式,action 分扁平对象和函数。
  • 在之前的项目中 thunk 方式用的比较多。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值