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);