You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将基于Redux-Thunk的API数据获取示例代码改写为Redux-Saga?

把Redux-Thunk的API请求示例重写为Redux-Saga

没问题!我来帮你把这段用Redux-Thunk实现的API请求代码改成Redux-Saga版本,咱们一步步拆解,保证逻辑清晰易懂。

首先,你需要先安装Redux-Saga的依赖:

npm install redux-saga axios

接下来,咱们从核心逻辑开始重构:

1. 保留原有的Reducer和Action Types

Reducer部分基本不需要改动,不过我先帮你修正一个小bug:原来的endFetchFun里的action type写错成PROCESS_FETCH了,应该改成END_FETCH,不然错误状态没法正确更新。

2. 编写Redux-Saga的核心逻辑

Redux-Saga用Generator函数来处理异步流程,我们需要两个核心函数:

  • Worker Saga:负责实际执行异步请求的逻辑
  • Watcher Saga:监听特定的action,一旦触发就调用对应的Worker Saga

3. 配置Saga中间件并创建Store

把原来的Thunk中间件替换成Saga中间件,然后启动Saga监听。

完整重写后的代码

import React from 'react';
import { createStore, applyMiddleware } from 'redux';
import ReactDOM from "react-dom";
import createSagaMiddleware from 'redux-saga'; // 导入saga中间件
import { takeEvery, call, put } from 'redux-saga/effects'; // saga核心API
import axios from 'axios';

function App(props) {
  // 初始状态保持不变
  const initialState = {
    loading: false,
    data: [],
    error: ''
  };

  // Reducer 修正了endFetch的type错误
  const reducer = function (state = initialState, action) {
    switch (action.type) {
      case 'START_FETCH':
        return { ...state, loading: true };
      case 'PROCESS_FETCH':
        return { ...state, loading: false, data: action.payload, error: "" };
      case 'END_FETCH':
        return { ...state, loading: false, data: [], error: action.payload };
      default:
        return state;
    }
  };

  // Action Types
  const START_FETCH = 'START_FETCH';
  const PROCESS_FETCH = 'PROCESS_FETCH';
  const END_FETCH = 'END_FETCH';
  const FETCH_USERS_REQUEST = 'FETCH_USERS_REQUEST'; // 新增一个触发saga的action type

  // Action Creators
  const startFetchFun = () => ({ type: START_FETCH });
  const processFetchFun = (users) => ({ type: PROCESS_FETCH, payload: users });
  const endFetchFun = (error) => ({ type: END_FETCH, payload: error });
  const fetchUsersRequest = () => ({ type: FETCH_USERS_REQUEST }); // 触发saga的action

  // Worker Saga: 执行异步请求逻辑
  function* fetchUsersSaga() {
    try {
      yield put(startFetchFun()); // 发送开始请求的action
      // 用call调用异步函数,axios.get返回Promise
      const response = yield call(axios.get, 'https://jsonplaceholder.typicode.com/users');
      yield put(processFetchFun(response.data)); // 请求成功,发送数据action
    } catch (error) {
      yield put(endFetchFun(error.message)); // 请求失败,发送错误action
      console.log(error.message);
    }
  }

  // Watcher Saga: 监听FETCH_USERS_REQUEST action,每次触发都调用fetchUsersSaga
  function* watchFetchUsers() {
    yield takeEvery(FETCH_USERS_REQUEST, fetchUsersSaga);
  }

  // 创建saga中间件并启动watcher
  const sagaMiddleware = createSagaMiddleware();
  const store = createStore(reducer, applyMiddleware(sagaMiddleware));
  sagaMiddleware.run(watchFetchUsers); // 启动saga监听

  // 订阅store变化,打印状态
  store.subscribe(() => {
    console.log(store.getState())
  });

  // 现在dispatch的是触发saga的action,而不是thunk函数
  store.dispatch(fetchUsersRequest());

  return (
    <div className="main">
      <h1>Redux-Saga</h1>
    </div>
  );
}

ReactDOM.render(
  <App/>,
  document.getElementById('root')
);

关键知识点解释

  • takeEvery:监听每一个FETCH_USERS_REQUEST action,只要这个action被dispatch,就会执行对应的fetchUsersSaga
  • call:用来调用异步函数(比如axios.get),它会等待Promise完成后再继续执行generator
  • put:相当于Redux里的dispatch,用来发送action给reducer更新状态
  • 和Thunk的区别:Thunk是把异步逻辑写在action creator里,而Saga是把异步逻辑抽离到单独的generator函数中,让action creator回归纯粹的“创建action”的职责,逻辑更清晰,也更方便处理复杂的异步流程(比如取消请求、重试等)

内容的提问来源于stack exchange,提问作者user10201522

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:06:36