将精简器中的重复逻辑移至实用功能

时间:2020-07-06 09:49:56

标签: javascript arrays redux react-redux

我一直试图在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中编写的逻辑一样。 有人可以帮忙吗,如何使该功能相应地起作用,或者我可以遵循任何其他选择将该逻辑移至实用程序功能。 预先感谢。

1 个答案:

答案 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;
}

因此,您正在做两件事:

  1. 您正在更新具有某些id(作为utilit函数的参数传递)的项。
  2. 您正在以某种方式(但可能有所不同)更新所有其他项目。

因此,您需要传递另一个更新程序作为实用程序函数的参数:

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),
}));