Redux observable 不处理后端响应
Redux observable doesn't handle backend response
我正在为后端调用实现史诗。未按预期处理响应。
对于我的实现,我使用了这些模块:
- "axios": "^0.17.1",
- "redux-observable": "^1.1.0",
- "rxjs": "^6.5.2",
- "typesafe-actions": "^4.4.0"
Action.ts
export const callBackendAction = createStandardAction('data/GET')();
export const callBackendCompletedAction = createStandardAction('data/LOADED')<IResultDataDTO[]>();
Epic.ts
export const callBackendEpic: Epic<RootAction, RootAction> = action$ =>
action$.pipe(
filter(isActionOf(callBackendAction)),
switchMap(async () =>
from(axiosBackendCall())
.pipe(
switchMap(({ data }) => {
return of(callBackendCompletedAction(data.map(data)))
}),
catchError(error => of(console.log(error)))
)
),
catchError(error => of(console.log(error)))
);
Reducer.ts
export interface IcallBackendReducerState
{
data: {}[];
pending: boolean;
}
const initialState : ICallBackendReducerState =
{
data: [],
pending: false
}
export const callBackendReducer = createReducer(initialState)
.handleAction(callBackendAction, (state: ICallBackendReducerState): ICallBackendReducerState => (
{ ...state, pending: true }
))
.handleAction(callBackendCompletedAction, (state: ICallBackendReducerState, action: PayloadAction<string, any>) => ({
...state,
pending: false,
data: action.payload
}));
Redux 抛出一个可能与此问题相关的错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
我的预期输出是一个后端调用,它会触发 reducer 将挂起状态设置为 true。 <--- 这与实际输出匹配
通过接收响应,reducer 应该被触发以使用数据和未决状态 false 更新状态。 <--- 这不会发生
在我的浏览器中查看网络流量表明调用确实完成了。问题是没处理好
看来问题出在这两行:
switchMap(async () =>
from(axiosBackendCall())
通过使用 async
你使内部函数 return 成为一个 Promise 但随后你使用 from()
那 return 是一个 Observable 所以实际上这个箭头函数 return Promise<Observable>
这不是你想要的。 switchMap
只会订阅 Promise 而不是嵌套的 Observable 所以 redux
很困惑为什么你传递的不是一个动作 Observable
.
所以修复很简单,只是不要使用 async
因为你甚至不需要它。 from
将自动处理 return 来自 axiosBackendCall()
的承诺(我假设 axiosBackendCall
return 是一个承诺)。
switchMap(() =>
from(axiosBackendCall())
.pipe(...)
),
我正在为后端调用实现史诗。未按预期处理响应。
对于我的实现,我使用了这些模块:
- "axios": "^0.17.1",
- "redux-observable": "^1.1.0",
- "rxjs": "^6.5.2",
- "typesafe-actions": "^4.4.0"
Action.ts
export const callBackendAction = createStandardAction('data/GET')();
export const callBackendCompletedAction = createStandardAction('data/LOADED')<IResultDataDTO[]>();
Epic.ts
export const callBackendEpic: Epic<RootAction, RootAction> = action$ =>
action$.pipe(
filter(isActionOf(callBackendAction)),
switchMap(async () =>
from(axiosBackendCall())
.pipe(
switchMap(({ data }) => {
return of(callBackendCompletedAction(data.map(data)))
}),
catchError(error => of(console.log(error)))
)
),
catchError(error => of(console.log(error)))
);
Reducer.ts
export interface IcallBackendReducerState
{
data: {}[];
pending: boolean;
}
const initialState : ICallBackendReducerState =
{
data: [],
pending: false
}
export const callBackendReducer = createReducer(initialState)
.handleAction(callBackendAction, (state: ICallBackendReducerState): ICallBackendReducerState => (
{ ...state, pending: true }
))
.handleAction(callBackendCompletedAction, (state: ICallBackendReducerState, action: PayloadAction<string, any>) => ({
...state,
pending: false,
data: action.payload
}));
Redux 抛出一个可能与此问题相关的错误:
Error: Actions must be plain objects. Use custom middleware for async actions.
我的预期输出是一个后端调用,它会触发 reducer 将挂起状态设置为 true。 <--- 这与实际输出匹配
通过接收响应,reducer 应该被触发以使用数据和未决状态 false 更新状态。 <--- 这不会发生
在我的浏览器中查看网络流量表明调用确实完成了。问题是没处理好
看来问题出在这两行:
switchMap(async () =>
from(axiosBackendCall())
通过使用 async
你使内部函数 return 成为一个 Promise 但随后你使用 from()
那 return 是一个 Observable 所以实际上这个箭头函数 return Promise<Observable>
这不是你想要的。 switchMap
只会订阅 Promise 而不是嵌套的 Observable 所以 redux
很困惑为什么你传递的不是一个动作 Observable
.
所以修复很简单,只是不要使用 async
因为你甚至不需要它。 from
将自动处理 return 来自 axiosBackendCall()
的承诺(我假设 axiosBackendCall
return 是一个承诺)。
switchMap(() =>
from(axiosBackendCall())
.pipe(...)
),