为什么Redux Saga中yield call返回函数而非实际请求数据?
问题根因
你定义的fetchTodos是一个Redux Thunk 风格的函数,调用后返回的是一个接收dispatch作为参数的异步函数,并不是直接返回请求结果。你用call(fetchTodos)执行时,拿到的就是它返回的这个匿名异步函数,自然不是你要的接口数据。
修复方案
方案1(推荐):直接在Saga中调用API,移除Thunk依赖
你已经在使用Redux Saga管理异步逻辑,不需要混用Thunk写法,直接调整Saga代码即可:
修改/src/sagas/todos/index.js:
// 先引入todosAPI import todosAPI from '../../services/api/todos' export function* fetchTodosSaga() { console.log('Ready to fetch Todos ...'); try { // 直接call接口请求方法,拿到axios返回结果 const getTodosResponse = yield call(todosAPI.getTodos); const _todos = getTodosResponse.data; console.log(_todos); // 此时就是正确的接口数据 yield put({ type: "FETCH_TODOS_FULFILLED", payload: { todos: _todos } }); } catch (e) { yield put({ type: "USER_FETCH_FAILED", message: e.message }); } return 'Hello'; }
多余的fetchTodosThunk函数可以直接废弃,不需要再使用。
方案2:如果需要保留现有Thunk函数,调整调用方式
如果你的业务场景必须保留fetchTodos这个Thunk方法,可以手动执行它返回的异步函数,传入dispatch:
import { fetchTodos } from '../../actions/sagas/todos' export function* fetchTodosSaga() { console.log('Ready to fetch Todos ...'); try { // 先执行fetchTodos拿到返回的异步函数,再call这个异步函数,传入saga的put作为dispatch const fetchTodosThunk = fetchTodos(); const _todos = yield call(fetchTodosThunk, put); console.log(_todos); // 此时得到正确数据 // 注意:你的Thunk内部已经dispatch了fetchTodosAction,这里不需要再重复put成功事件,避免重复触发 } catch (e) { yield put({ type: "USER_FETCH_FAILED", message: e.message }); } return 'Hello'; }
注意:该方案会导致你在Thunk和Saga中两次触发事件,冗余且不好维护,更推荐使用方案1。
内容的提问来源于stack exchange,提问作者tommychoo
相关产品推荐
相关产品推荐

