-
redux-saga是通过ES6中Generator实现的,本质是一个可以自执行的generator
-
通过dispatch(action)进行触发,然后通过监听action.type,其中值得注意的是takeEvery监听的action.type不要和put触发action.type一样,不然会反复执行
-
put相当于dispatch一样的效果
-
redux-saga 跟 redux-thunk 区别就在于 redux-saga 独立出一个单独的文件,通过自身的API来监听dispatch的action.type,来进行一些其他的操作,然后再通过自身的API(put方法)其他重新dispatch给reducer进行操作。
-
redux-thunk的效果就是让dispatch(action)变为也可以dispatch(function),当dispatch函数的时候,会自动执行该函数,然后在函数里做一些其他操作,最后在函数里重新dispatch(action)
基本用法介绍
-
其他不用细看主要看saga文件,我此处的action以及action.type都不是通过变量返回,actionTypes.js和actionCreators.js虽然定义了,但为了方便和直观不使用变量。
-
至于reducer也是定义好的,主要就是判断action.type然后操作state数据,跟redux-saga和redux-thunk的应该并不影响。
// store/index.js
import { createStore, compose, applyMiddleware } from 'redux'
import reducer from './reducer'
import createSagaMiddleware from 'redux-saga'
import rootSaga from './saga'
// 创建saga中间件
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// 创建store
const store = createStore(reducer, composeEnhancers(applyMiddleware(sagaMiddleware)))
// 使用saga,好像得放到createStore后面
sagaMiddleware.run(rootSaga)
export default store
// store/reducer.js
// 返回一个reducer函数,让createStore用来创建store
// 导入actionTypes.js中的type类型,方便我们进行识别操作
import {
A,
B
} from './actionTypes.js'
// formJS将JS对象转化为immutable对象
import { fromJS } from 'immutable'
const defaultState = fromJS({
valueA: '',
valueB: ''
})
// 只能间接修改state
const reducer = (state = defaultState, action) => {
if (action.type === A) {
return state.set('valueA', action.value)
} else if (action.type === B) {
return state.set('valueB', action.value)
}
return state
}
export default reducer
- saga.js
// import { A } from './actionTypes';
import { takeEvery, put } from 'redux-saga/effects';
function* getInitList() {
console.log(1)
try {
yield put({
type: 'A',
value: 'milo'
});
} catch (e) {
console.log(e);
}
}
export default function* rootSaga() {
yield takeEvery('CHANGE', getInitList);
}
- 组件直接dispatch(action),saga就可以监听到了
多个saga合并成一个根saga,跟多个reducer一样
- 根store,项目文件/src/store/index.js
import { createStore, compose, applyMiddleware } from 'redux';
import createSagaMiddleware from 'redux-saga';
import reducer from './reducer';
import rootSaga from './saga'
const sagaMiddleware = createSagaMiddleware()
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, composeEnhancers(applyMiddleware(sagaMiddleware)));
sagaMiddleware.run(rootSaga)
export default store;
- src/store/reducer.js
- src/store/saga.js
import { fork, all } from 'redux-saga/effects'
// 异步逻辑
import { homeSaga } from './../pages/home/store'
import { loginSaga } from './../pages/login/store'
// 单一进入点,一次启动所有Saga
export default function* rootSaga() {
yield all([fork(homeSaga), fork(loginSaga)])
}
- home组件的store/index.js
- home组件的store/reducer.js
- home组件的store/saga.js
import { takeEvery, put } from 'redux-saga/effects';
function* getInitList() {
console.log(1)
try {
yield put({
type: 'HOME_TYPE',
value: '你好,milo'
});
} catch (e) {
console.log(e);
}
}
export function* homeSaga() {
yield takeEvery('CHANGE_HOME', getInitList);
yield takeEvery('CHANGE_A', getInitList);
}
- home组件进行dispatch
- login组件跟home组件一样