Javascript 将具有完全相同代码的ExtraReducer与redux toolkit相结合
我用redux工具包创建了一个全局错误处理切片。我想对其进行重构,使其更加“干燥”: 两个外减速器执行完全相同的操作,有效负载正常化。我的代码可以正常工作Javascript 将具有完全相同代码的ExtraReducer与redux toolkit相结合,javascript,reactjs,redux-toolkit,Javascript,Reactjs,Redux Toolkit,我用redux工具包创建了一个全局错误处理切片。我想对其进行重构,使其更加“干燥”: 两个外减速器执行完全相同的操作,有效负载正常化。我的代码可以正常工作 有没有一种方法可以将2“组合”到一个extraReducer中(最终会更多)?我认为没有一种方法可以将两个case reducer组合到一个case reducer中,但您肯定可以为每个case reducer提供相同的功能。将重复的reducer函数重构为单个公共reducer函数 const rejectionReducer = (sta
有没有一种方法可以将2“组合”到一个extraReducer中(最终会更多)?我认为没有一种方法可以将两个case reducer组合到一个case reducer中,但您肯定可以为每个case reducer提供相同的功能。将重复的reducer函数重构为单个公共reducer函数
const rejectionReducer = (state, { payload }) => {
const errorArray = Object.values(payload.message).map(
(key) => key.message
);
state.errors = errorArray;
state.isOpen = true;
};
...
const errorsSlice = createSlice({
name: "error",
initialState,
reducers: {
clearError: (state) => {
state.errors = null;
state.isOpen = false;
},
},
extraReducers: {
[createScript.rejected]: rejectionReducer,
[createScene.rejected]: rejectionReducer,
});
更新
使用isRejectedWithValue
高阶函数,您可以将thunk动作组合到匹配器中
import { isRejectedWithValue } from '@reduxjs/toolkit';
const rejectionReducer = (state, { payload }) => {
const errorArray = Object.values(payload.message).map(
(key) => key.message
);
state.errors = errorArray;
state.isOpen = true;
};
const errorsSlice = createSlice({
name: "error",
initialState,
reducers: {
clearError: (state) => {
state.errors = null;
state.isOpen = false;
},
},
extraReducers: builder => {
builder.addMatcher(
isRejectedWithValue(createScript, createScene), // <-- thunk actions
rejectionReducer
);
},
});
从'@reduxjs/toolkit'导入{isRejectedWithValue};
const rejectionReducer=(状态,{payload})=>{
const errorArray=Object.values(payload.message).map(
(key)=>key.message
);
state.errors=errorArray;
state.isOpen=true;
};
const errorsSlice=createSlice({
名称:“错误”,
初始状态,
减速器:{
clearError:(状态)=>{
state.errors=null;
state.isOpen=false;
},
},
外部减速器:生成器=>{
builder.addMatcher(
isRejectedWithValue(createScript,CreateSecene),//您当前正在使用定义您的外部还原程序。您想改用
使用生成器回调,您可以使用.addCase()
匹配单个操作,但也可以使用.addMatcher()
处理多个操作。addMatcher()的第一个参数
是一个函数,它执行操作
,并返回一个布尔值
,判断它是否匹配。这里我们要匹配所有以'/rejected'
结尾的操作
const errorsSlice = createSlice({
name: "error",
initialState,
reducers: {
clearError: (state) => {
state.errors = null;
state.isOpen = false;
}
},
extraReducers: (builder) =>
builder.addMatcher(
// matcher function
(action) => action.type.endsWith("/rejected"),
// case reducer
(state, { payload }) => {
const errorArray = Object.values(payload.message).map(
(key) => key.message
);
state.errors = errorArray;
state.isOpen = true;
}
)
});
@PixAff啊,很好的发现。我想我理解这一切是如何工作的,但是isRejectedWithValue
高阶函数似乎只有在thunk使用rejectWithValue
操作实用程序时才起作用。看起来isRejectedWithValue
可以组成多个操作,并将错误放在有效负载
属性上,然后重试rn在额外的还原器中只需“倾听”一个动作。答案很好-这绝对解决了问题。无论如何,我在redux toolkit文档中找到了一些可能也是解决方案的东西:redux toolkit.js.org/api/matching utilities#isrejectedwithvalue,但我没有对它感到困惑。。。(我的操作是带有rejectWithValue回调的异步thunks)抱歉,我无意中删除了我的评论(想要编辑)-是的,我的操作是带有rejectWithValue的异步Thunkcallback@PixAff不幸的是,我对redux工具箱世界中的redux thunk环境不是很熟悉。我大约一个月前才开始使用redux工具箱,但使用redux observables/rxjs进行异步操作。我已经用我认为应该有效的方法更新了我的答案(或者接近目标)(是我复习更多文档的时候了)。查看上的文档。您可以执行(action)=>action.type.endsWith('/rejected')
。谢谢!您认为Drews answer有任何缺点吗?好的,我自己发现了两个缺点:您需要(稍微)更多的代码,并且需要导入操作。
const errorsSlice = createSlice({
name: "error",
initialState,
reducers: {
clearError: (state) => {
state.errors = null;
state.isOpen = false;
}
},
extraReducers: (builder) =>
builder.addMatcher(
// matcher function
(action) => action.type.endsWith("/rejected"),
// case reducer
(state, { payload }) => {
const errorArray = Object.values(payload.message).map(
(key) => key.message
);
state.errors = errorArray;
state.isOpen = true;
}
)
});