我在 saga 中使用 Axios 发出 GET 请求,完成后,我将执行一个指示成功响应的操作。
my-saga.ts
import { throttle, call, put } from "redux-saga/effects";
import axios from "axios";
import { SuccessfulResponse } from "@/types";
export function* apiWorker() {
const response: SuccessfulResponse = yield call(
axios.get,
"https://my-url.com/api"
);
yield put(apiSuccess(response.data.Items));
}
export default function* apiWatcher() {
yield throttle(1000, "API_REQUEST", apiWorker);
}
我的动作设置正常:
my-actions.ts
import { createAction } from "@reduxjs/toolkit";
import { Items } from "@/types";
export const apiRequest = createAction("API_REQUEST");
export const apiSuccess = createAction(
"API_SUCCESS",
(items: Items) => ({
payload: { items },
})
);
和我的店一样:
my-store.ts
import { createReducer } from "@reduxjs/toolkit";
import { ItemsContainer } from "@/types";
const initialState: ItemsContainer = {};
const rootReducer = createReducer(initialState as ItemsContainer, (builder) => {
builder
.addCase(apiRequest, (_state) => ({}))
.addCase(apiSuccess, (_state, action) => action.payload);
});
export default rootReducer;
有了给定的传奇,当我进行 API 调用时,我得到了成功的响应(我有
console.logged
响应并且符合预期)。它触发apiSuccess
,我可以验证apiSuccess
案例接收到正确的数据并运行(我有console.logged
我的Items
声明中的addCase
apiSuccess
)。
但是状态永远不会完成更新。尽管我可以验证我正在运行那个案例,并且我得到了正确的负载,但无论我如何设置状态(无论是使用 return 语句还是直接设置
state.items
属性),状态都不会更新。此外,即使 apiSuccess
reducer 案例正在运行,我的浏览器的 Redux Devtools 扩展也从未显示 API_SUCCESS
动作被发送,只有 API_REQUEST
动作。
更奇怪的是,当我用一些示例数据替换 Axios 调用时,整个事情运行得很好,并且状态更新正确。好像跟
yield calling
axios有关
我试过用 fetch 替换 Axios,并创建一个中介
callApi
函数来像这样包装承诺:
const callApi = async (url: string) => {
try {
return await axios.get(url);
} catch (error) {
throw error;
}
}
似乎没有任何效果。如果我从 Axios 或 fetch 收到错误响应,那将是有道理的,但我没有。
TL;DR 我不明白为什么在 Redux Saga 的
yield call
语句中使用 Axios 进行简单的 API 调用会阻止以下 yield put
语句成功终止和状态更新——有什么想法我接下来应该尝试什么吗?