Redux-saga

基本概念

redux-saga 可以将异步操作从 Action Creator 文件中抽离出来,放在一个单独的文件中。

  1. redux-saga 下载
    1. npm install redux-saga
  1. 创建 redux-saga中间件
    1. import createSagaMiddleware from 'redux-saga';
    2. const sagaMiddleware = createSagaMiddleware();
  1. 注册redux-saga
    1. createStore(reducer, applyMiddleware(sagaMiddleware));
  1. 使用saga 接收 action 执行异步操作

    • takeEvery 作用是接收action,当组件去触发一个action的时候,在saga文件中用takeEvery 去接收这个action;
    • takeEvery第一个参数接收的是那个action的类型字符串;
    • takeEvery第二个参数接收的是接收到action后要执行的方法,这是一个Generator函数;
    • put 当异步操作返回结果之后,put去触发另一个action把异步操作结果传递给reducer,让reducer把结果保存到store中。 ```javascript import { takeEvery, put } from ‘redux-saga/effects’;

function* load_posts () { const { data } = yield axios.get(‘/api/posts.json’); yield put(load_posts_success(data)); }

export default function* postSaga () { yield takeEvery(LOAD_POSTS, load_posts); }

  1. 5.
  2. 启动saga
  3. ```javascript
  4. import postSaga from './store/sagas/post.saga';
  5. sagaMiddleware.run(postSaga);

action 传参

  1. 接收参数
    1. // components/Counter.js
    2. const { increment } = props;
    3. ...
    4. <button onClick={() => increment_async(20)}>+</button>
  1. View 传递给 action ```javascript // counter.action.js import { INCREMENT_ASYNC } from “../const/counter.const”;

export const increment_async = payload => ({type: INCREMENT_ASYNC, payload});

  1. 3.
  2. saga 接收 action
  3. ```javascript
  4. import { takeEvery, put, delay } from 'redux-saga/effects';
  5. import { increment } from '../actions/counter.action';
  6. import { INCREMENT_ASYNC } from '../const/counter.const';
  7. function* increment_async_fn(action) {
  8. yield delay(2000);
  9. yield put(increment(action.payload));
  10. }
  11. export default function* counterSaga() {
  12. // 接收action
  13. // takeEvery第一个参数接收字符串,第二个接收异步函数
  14. yield takeEvery(INCREMENT_ASYNC, increment_async_fn);
  15. }

拆分 Saga

  1. // 新建modal.saga.js
  2. import { takeEvery, put, delay } from 'redux-saga/effects';
  3. import { show } from '../actions/modal.action';
  4. import { SHOWMODAL_ASYNC } from '../const/counter.const';
  5. function* increment_async_fn(action) {
  6. yield delay(2000);
  7. yield put(increment(action.payload));
  8. }
  9. export default function* counterSaga() {
  10. yield takeEvery(SHOWMODAL_ASYNC, showModal_async_fn);
  11. }

合并 saga

  • 使用 all 方法合并 saga
  • import { all } from ‘redux-saga/effects’;
  • all 接收一个 saga 函数的数组;
  • 导出的 rootSaga 是一个Generator函数,function*,yield all。
  1. // 新建 saga/root.saga.js
  2. import { all } from 'redux-saga/effects';
  3. import counterSaga from './counter.saga';
  4. import modalSaga from './modal.saga';
  5. export default function* rootSaga() {
  6. yield all([
  7. counterSaga(),
  8. modalSaga()
  9. ])
  10. }
  11. // 修改 store/index.js
  12. import rootSaga from './saga/root.saga';
  13. sagaMiddleware.run(rootSaga);