Redux-saga 中间件

本文介绍如何使用Redux-Saga中间件管理应用中的异步操作。通过替换redux-thunk,使用Redux-Saga可以更优雅地处理异步流程。文章详细介绍了安装配置步骤及如何将组件中的异步请求迁移到sagas中。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前我们使用redux-thunk 把异步代码放到了action 里面,这个解决了自动化测试的一些问题以及代码的拆分管理。

redux-saga 也是做异步代码拆分的中间件,可以把它将 redux-thunk 互换。

我们要使用redux-saga,先把之前redux-thunk 相关代码删掉。

然后,我们在github 上找到 redux-saga : https://github.com/redux-saga/redux-saga

按照github 中的文档,我们先下载按照 redux-saga ,使用命令

yarn add redux-saga

安装好啦后,我们就开始使用了。首先在store 文件中,引入并使用,如下。

import { createStore, applyMiddleware } from 'redux';
// import thunk from 'redux-thunk';
import reducer from './reducer';
import createSagaMiddleware from 'redux-saga';
import mySaga from './sagas';

const sagaMiddleware = createSagaMiddleware()

const store = createStore(
    reducer,
    // applyMiddleware(thunk)
    applyMiddleware(sagaMiddleware)
);
sagaMiddleware.run(mySaga);

export default store;

然后,我们在store 文件夹下新建一个sagas.js ,我们把异步代码都放这儿。

我们先把github 上 sagas.js 中后面几行代码拷到 sagas.js (必须有一个函数是generator函数)中,如下。

function* mySaga() {
  //yield takeLatest("USER_FETCH_REQUESTED", fetchUser);
}

export default mySaga;

下面,我们要将组件中axios 异步代码,移到sagas.js 中,

首先,我们创建一个action 模版把

export const getInitListAction = () => ({
  type: GET_INIT_LIST
})

然后在组件中使用,并传给redux

  componentDidMount() {
    const action =  getInitListAction();
    store.dispatch(action);
    console.log(action);
  }

然后呢,在传给store之前,我们在saga中处理它,进入sagas.js 文件,进行修改:(下面的意思是,saga 只要捕获到 GET_INIT_LIST 就会执行 fetchUser方法)

import { takeEvery } from 'redux-saga/effects';
import {GET_INIT_LIST} from './actionTypes';

function* mySaga() {
  yield takeEvery( GET_INIT_LIST, fetchUser);
}

export default mySaga;

下面我们来写一个fetchUser方法,如下。 fetchUser 方法可以是普通方法也可以是gennerator 方法,建议写generator 方法。

import { takeEvery } from 'redux-saga/effects';
import store from './index.js';
import {GET_INIT_LIST} from './actionTypes';
import axios from 'axios';
import {
  initListAction
} from './actionCreators';

function* initList () {
  axios.get('api/list.json', {dataType: 'json'}).then((res) => {
      const action = initListAction(res.data.names);
      store.dispatch(action);
    })
}

function* mySaga() {
  yield takeEvery( GET_INIT_LIST, initList);
}

export default mySaga;

上面代码,好像没问题,但是redux-saga 给我们提供了put 方法,就不用store 的dispatch 了,如下。【在generator 函数 里,做异步请求的话,就不要用Promise了,完全可以用yield】

import { takeEvery, put } from 'redux-saga/effects';
import {GET_INIT_LIST} from './actionTypes';
import axios from 'axios';
import {
  initListAction
} from './actionCreators';

function* initList () {
  const res = yield axios.get('api/list.json');
  const action = initListAction(res.data.names);
  yield put(action);
}

function* mySaga() {
  yield takeEvery( GET_INIT_LIST, initList);
}

export default mySaga;

我们可以给 yield 加一个try 如下。

function* initList () {
  try {
    const res = yield axios.get('api/list.json');
    const action = initListAction(res.data.names);
    yield put(action);
  } catch(e) {
    console.log("list.json 请求失败")
  }
}

然后组件中只需要如下代码。即可使用异步代码。

  componentDidMount() {
    const action =  getInitListAction();
    store.dispatch(action);
    
  }

Done

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值