我一直试图在redux reducer中编写一些代码,这些代码的状态更新逻辑相似。 我的初始状态如下:
const initialState = {
isLoading: false,
events: [
{
year: 2021,
place: [
{
id: 1,
name: "BD",
address:[{id:1,text:"test"}]
},
{
id: 2,
name: "BD Test"
address:[{id:5,text:"test one"}]
}
]
}
]
};
而且,我已经像这样更新了reducer中的状态:
...state,
events: state.events.map((event) => ({
...event,
place: event.place.map((place) => {
const address = place.address.find((x) => x.id === action.addressId);
if (address) {
return {
...place,
address: place.address.map((el) => {
if (el.id === action.addressId) {
return { ...el, isChanged:true };
}
return { ...el, isChanged:false };
}),
};
}
return place;
}),
})),
在一些我刚刚添加了一些额外属性的地方(例如本例"isChanged:true" and "isChanged:false"
),我一直在类似地使用这种逻辑。这部分编码似乎是重复的,因此,到目前为止,我尝试编写这样的实用程序函数:
const updateAddress = (years, addressId, update) => years.map((year) => ({
...year,
place: year.place.map((place) => place.address.find((el) => el.id === addressId)
? {
...place,
address: place.address.map(
(el) => el.id === addressId ? update(x) : x
),
}
: place),
}));
此实用程序功能运行良好,但仅在el.id === addressId
变为true
并仅添加isChanged:true
时更新工作。但是,我还需要将isChanged:false
添加到其他地址,就像在reducer中编写的逻辑一样。
有人可以帮忙吗,如何使该功能相应地起作用,或者我可以遵循任何其他选择将该逻辑移至实用程序功能。
预先感谢。
答案 0 :(得分:1)
如果我可以按照您的“实用功能”的实现进行操作,则解决方案很简单。在您的原始实现中,这是
place.address.map((el) => {
if (el.id === action.addressId) {
return { ...el, isChanged:true };
}
return { ...el, isChanged:false };
}
这是(以更清晰易读的方式):
place.address.map((el) => {
let newElState;
if (el.id === action.addressId) {
newElState = { ...el, isChanged:true };
} else {
newElState = { ...el, isChanged:false };
}
return newElState;
}
因此,您正在做两件事:
因此,您需要传递另一个更新程序作为实用程序函数的参数:
const updateAddress = (years, addressId, updateId, updateOthers) => years.map((year) => ({
...year,
place: year.place.map((place) => place.address.find((el) => el.id === addressId)
? {
...place,
address: place.address.map(
// this arrow function works in the same way as the code snippet above:
// 1. if an address in the place.address arrray has the same id
// as id passed in addressId, the callback updateId will be called
// 2. if an address in the place.address arrray does not have the same id
// as id passed in addressId, the callback updateOthers will be called
//
// what really updateId, or updateOthers do depends on their implementation,
// what the caller of updateAddress put as the third and the fourth argument
(el) => el.id === addressId ? updateId(el) : updateOthers(el)
),
}
: place),
}));