Redux深度克隆-状态始终相等

时间:2019-10-12 06:29:36

标签: javascript reactjs object redux

我在React Redux中具有以下reducer:

export const reducer = (state = initialStateData, action) => {
    switch (action.type) {
      case Action.TOGGLE_ARR_FILTER:
        {
          const subArr = state.jobOffers.filters[action.key];
          const filterIdx = subArr.indexOf(action.value[0]);
          const newArr = { ...state.jobOffers.filters
          };

          if (filterIdx !== -1) {
            newArr[action.key].splice(filterIdx, 1);
          } else {
            newArr[action.key].push(action.value[0]);
          }

          return {
            ...state,
            jobOffers: {
              ...state.jobOffers,
              filters: {
                ...newArr,
              },
            },
          };
        }

这是我的对象

const initialStateData = {
  jobOffers: {
    filters: {
      employments: [],
      careerLevels: [],
      jobTypeProfiles: [],
      cities: [],
      countries: [],
    },
    configs: {
      searchTerm: '',
      currentPage: 1,
      pageSize: 5,
    },
  },
};

减速器似乎可以正常工作,它可以正确切换值。

但是:Redux总是显示“状态相等”,这很糟糕,因为它无法识别更改。

有人可以帮忙吗?我以为我要返回一个新对象。

2 个答案:

答案 0 :(得分:1)

您可以使用Immer,redux还将它用于嵌套内容的不可变更新。 因此,您可以编写看上去处于“突变”状态的reduce,但实际上更新是一成不变的。

const initialStateData = {
  jobOffers: {
    filters: {
      employments: [],
      careerLevels: [],
      jobTypeProfiles: [],
      cities: [],
      countries: [],
    },
    configs: {
      searchTerm: '',
      currentPage: 1,
      pageSize: 5,
    },
  },
};
export const reducer = immer.produce((state = initialStateData, action) => {
    switch (action.type) {
      case Action.TOGGLE_ARR_FILTER:

            const subArr = state.jobOffers.filters[action.key];
            const filterIdx = subArr.indexOf(action.value[0]);
            const newArr = state.jobOffers.filters;

            if (filterIdx !== -1) 
              newArr[action.key].splice(filterIdx, 1);
            else 
              newArr[action.key].push(action.value[0]);

            return state;
           }
          })        

答案 1 :(得分:0)

尽管您复制了state.jobOffers.filters,但这仍然保留了对诸如employments之类的原始子数组的引用。因此,当您使用newArr[action.key]splice突变push时,Redux将不会看到该更改,因为它仍然是相同的数组引用。

您可以替换为:

if (filterIdx !== -1) {
  newArr[action.key].splice(filterIdx, 1);
} else {
  newArr[action.key].push(action.value[0]);
}

具有:

newArr[action.key] = filterIdx !== -1 
    ? [...newArr[action.key].slice(0, filterIdx), ...newArr[action.key].slice(filterIdx+1)]
    : [...newArr[action.key], action.value[0]]);

顺便说一句,您不必再次复制newArr ,因为它已经是filters的副本。您可以替换:

filters: {
    ...newArr,
},

通过:

filters: newArr,