saga常用几种方法
takeEvery(pattern, saga, ...args) 快速点击多次时都会触发
takeLatest(channel, saga, ..args) 快速点击多次时取消之前的方法,执行最后一次
throttle(ms, pattern, saga, ..args) 快速点击多次时Nms执行一次,采用节流方式
put(action) 提交action到reducer修改reducer的值
call([context, fnName], ...args) 发起请求
select(selector, ...args) 获取action提交的参数
其它 详细请参考:https://redux-saga-in-chinese.js.org/docs/api/
安装saga到项目 main.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { createStore, applyMiddleware } from 'redux' import createSagaMiddleware from 'redux-saga' import reducer from './reducers' import mySaga from './sagas' const sagaMiddleware = createSagaMiddleware ()const store = createStore ( reducer, applyMiddleware (sagaMiddleware) ) sagaMiddleware.run (mySaga)
mySaga.js 1 2 3 4 5 6 import { call, put, takeEvery, takeLatest } from 'redux-saga/effects' function * mySaga ( ) { yield takeLatest ("USER_FETCH_REQUESTED" , fetchUser); } export default mySaga;
reducer.js 为了让select获取原state,和action提交 的参数,需要对reducer修改
1 2 3 4 5 6 7 8 9 10 const reducer = (state, action ) => { const {type,payload} = action; if (type ==='add' ){ const arr = {...state,list :[payload,...state.list ]}; console .log (arr); return arr } return {...state,...action} } export default reducer;
通过dispatch({type:’USER_FETCH_REQUESTED’}) 提交相应action
call常见三种异步 1 2 3 4 5 6 7 8 const result = yield call (asyncReuqest,[payload,'http://www.baidu.com' ]); console .log (result);const result2 = yield call (axios.get ,'http://www.shaoyuhong.cn/lx104.php' ,{params :{page :2 }}); console .log (result2);const result3 = yield call (axios.post ,'http://www.shaoyuhong.cn/lx104.php' ,{page :2 }); console .log (result3);
saga.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { call, put,takeEvery, select,takeLatest } from 'redux-saga/effects' ;import axios from 'axios' ;const handleAddCountFn = function *(){ const page = yield select (state => state.payload .count ); const num = yield select (state => state.count ); const result = yield call (axios.get ,"http://www.shaoyuhong.cn/lx104.php" ,{params :{page :page+num}}); yield put ({ type :'addCount' , payload :{ num :page } }); yield put ({ type :'setList' , payload :{ list :result.data } }) };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const handleSubCountFn = function *(){ const page = yield select (state => state.payload .count ); const num = yield select (state => state.count ); const result = yield call (axios.get ,"http://www.shaoyuhong.cn/lx104.php" ,{params :{page :num - page}}); yield put ({ type :'subCount' , payload :{ num :page } }); yield put ({ type :'setList' , payload :{ list :result.data } }) }; function *saga ( ){ yield takeEvery ('requestAddCount' ,handleAddCountFn); yield takeLatest ('requestSubCount' ,handleSubCountFn) } export default saga;
app.js提交请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @connect ( state => { return { count :state.count , list :state.list } }, dispatch => { return { addCount ( ){ dispatch ({type :'requestAddCount' ,payload :{count :parseInt (Math .random () * 100 )}}) }, subCount ( ){ dispatch ({type :'requestSubCount' ,payload :{ count :100 }}) } } } )
reducer.js 参考 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const defaultState = { count :100 , list :['test' ] } export default function (state = Object .assign({},defaultState),action = {type:'' ,payload:{}} ){ let { type,payload} = action; if (type === 'addCount' ){ let obj = Object .assign ({},state); obj.count +=action.payload .num ; return obj; } if (type ==='subCount' ){ let obj = Object .assign ({},state); obj.count -=action.payload .num ; return obj; } if (type === 'setList' ){ let obj = Object .assign ({},state); obj.list = action.payload .list ; return obj; } return Object .assign ({},state,action); }
//注: app.js dispatch提交的事件名可以和reducer.js action.type名不同,dispatch提交的事件将在saga.js的takeEvery中被监听
使用saga.js需要在reducer中默认返回Object.assign({},state,action);