Redux 工具包 thunk 操作通用错误处理程序
Redux toolkit thunk action generic error handler
我很喜欢 redux-toolkit,但我想知道是否有办法为任何被拒绝的 thunk 添加通用错误处理程序?就像浏览器有您可以收听的 unhandledrejection 事件一样,我想向我的错误跟踪器报告任何被拒绝的承诺。
创建一个错误状态切片来保存全局错误并使用 isRejected 匹配函数来检查一个动作是否是来自 createAsyncThunk
承诺生命周期的 'rejected' 动作创建者。
例如
import { configureStore, createAsyncThunk, createSlice, isRejected, isRejectedWithValue } from '@reduxjs/toolkit';
const thunkA = createAsyncThunk('a', async (_, thunkAPI) => {
return thunkAPI.rejectWithValue('error a');
});
const thunkB = createAsyncThunk('b', async (_, thunkAPI) => {
return Promise.reject('error b');
});
const thunkC = createAsyncThunk('c', async (_, thunkAPI) => {
return { name: 'c' };
});
const thunkASlice = createSlice({
name: 'thunkA',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkBSlice = createSlice({
name: 'thunkB',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkCSlice = createSlice({
name: 'thunkC',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const errorSlice = createSlice({
name: 'error',
initialState: {
message: '',
},
reducers: {},
extraReducers: (builder) => {
builder.addMatcher(isRejected, (state, action) => {
// global error handle reducer
state.message = 'some thunk rejected';
});
},
});
const store = configureStore({
reducer: {
error: errorSlice.reducer,
a: thunkASlice.reducer,
b: thunkBSlice.reducer,
c: thunkCSlice.reducer,
},
});
store.subscribe(() => {
console.log('state:', store.getState());
});
// store.dispatch(thunkA());
store.dispatch(thunkB());
store.dispatch(thunkC());
最终状态输出:
state: {
error: { message: 'some thunk rejected' },
a: { name: '' },
b: { name: '' },
c: { name: '' }
}
thunkA
和thunkB
是'rejected'动作,可以在errorSlice
reducer集中处理被拒绝的动作。
听起来您想在每次 thunk 被拒绝时 运行 产生副作用(向服务器发送消息)。我建议查看 our new "listener middleware" for Redux Toolkit,它特别允许您在调度某些操作时触发额外的逻辑。
侦听器中间件目前是一个单独的 @rtk-incubator/action-listener-middleware
包,因为我们一直在对其 API 进行迭代,但截至今天 API 已稳定,我们计划正式发布它很快就会成为 RTK 1.8 的一部分。您今天可以在该包中使用它,并在该版本发布后立即切换为从 RTK 导入它。
它可能是这样的:
// app/listenerMiddleware.js
import { isRejected } from '@reduxjs/toolkit';
import { createListenerMiddleware } from '@rtk-incubator/action-listener-middleware';
const listenerMiddleware = createListenerMiddleware()
listenerMiddleware.startListening({
matcher: isRejected,
effect: async (action, listenerApi) => {
// send a message to the server here containing info from the action
},
})
我很喜欢 redux-toolkit,但我想知道是否有办法为任何被拒绝的 thunk 添加通用错误处理程序?就像浏览器有您可以收听的 unhandledrejection 事件一样,我想向我的错误跟踪器报告任何被拒绝的承诺。
创建一个错误状态切片来保存全局错误并使用 isRejected 匹配函数来检查一个动作是否是来自 createAsyncThunk
承诺生命周期的 'rejected' 动作创建者。
例如
import { configureStore, createAsyncThunk, createSlice, isRejected, isRejectedWithValue } from '@reduxjs/toolkit';
const thunkA = createAsyncThunk('a', async (_, thunkAPI) => {
return thunkAPI.rejectWithValue('error a');
});
const thunkB = createAsyncThunk('b', async (_, thunkAPI) => {
return Promise.reject('error b');
});
const thunkC = createAsyncThunk('c', async (_, thunkAPI) => {
return { name: 'c' };
});
const thunkASlice = createSlice({
name: 'thunkA',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkBSlice = createSlice({
name: 'thunkB',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const thunkCSlice = createSlice({
name: 'thunkC',
initialState: { name: '' },
reducers: {},
extraReducers: (builder) => {
builder.addCase(thunkA.fulfilled, (state, action) => {
state.name = (action.payload as any).name;
});
},
});
const errorSlice = createSlice({
name: 'error',
initialState: {
message: '',
},
reducers: {},
extraReducers: (builder) => {
builder.addMatcher(isRejected, (state, action) => {
// global error handle reducer
state.message = 'some thunk rejected';
});
},
});
const store = configureStore({
reducer: {
error: errorSlice.reducer,
a: thunkASlice.reducer,
b: thunkBSlice.reducer,
c: thunkCSlice.reducer,
},
});
store.subscribe(() => {
console.log('state:', store.getState());
});
// store.dispatch(thunkA());
store.dispatch(thunkB());
store.dispatch(thunkC());
最终状态输出:
state: {
error: { message: 'some thunk rejected' },
a: { name: '' },
b: { name: '' },
c: { name: '' }
}
thunkA
和thunkB
是'rejected'动作,可以在errorSlice
reducer集中处理被拒绝的动作。
听起来您想在每次 thunk 被拒绝时 运行 产生副作用(向服务器发送消息)。我建议查看 our new "listener middleware" for Redux Toolkit,它特别允许您在调度某些操作时触发额外的逻辑。
侦听器中间件目前是一个单独的 @rtk-incubator/action-listener-middleware
包,因为我们一直在对其 API 进行迭代,但截至今天 API 已稳定,我们计划正式发布它很快就会成为 RTK 1.8 的一部分。您今天可以在该包中使用它,并在该版本发布后立即切换为从 RTK 导入它。
它可能是这样的:
// app/listenerMiddleware.js
import { isRejected } from '@reduxjs/toolkit';
import { createListenerMiddleware } from '@rtk-incubator/action-listener-middleware';
const listenerMiddleware = createListenerMiddleware()
listenerMiddleware.startListening({
matcher: isRejected,
effect: async (action, listenerApi) => {
// send a message to the server here containing info from the action
},
})