【问题标题】:How can I prevent a duplicate on Redux when using the spread operator?使用扩展运算符时如何防止 Redux 上的重复?
【发布时间】:2020-09-04 01:14:44
【问题描述】:

我正在这样做:

    case LOAD_PAGES:
      return {
        ...state,
        pages: [...state.pages, action.pages],
      };

我有一个组件,每次我进入它时,它都会将相同的数据发送到商店,所以我会得到很多重复的数据。

pages 数组如下所示:

pages: [
      {
        key: 0,
        menuName: 'Home',
        pageType: 'HomePage',
        dataIndex: 'HomePage0'
      },
      {
        key: 1,
        menuName: 'Employer Chat',
        pageType: 'EmployerChat',
        dataIndex: 'EmployerChat1'
      },
]

这是 React 组件:

  const handlePageLoad = () => {
    if (siteById.data) {
      siteById.data.pages.map((p, index) => {
        return loadPagesAction({
          key: index,
          menuName: p.menuName,
          pageType: p.pageType,
          dataIndex: p.pageType + index,
        });
      });
    }
  };

  useEffect(() => {
    if (siteById.data.pages.length) {
      handlePageLoad();
    }
  }, []);

有什么想法吗?

【问题讨论】:

  • 为什么要为所有页面发送loadPagesAction?你的目的是什么
  • @ShubhamKhatri 我必须根据这些页面呈现一个菜单列表。
  • 所以如果我理解正确的话,每个组件都是一个页面,当页面加载时,谁希望在 redux 中更新状态以便更改菜单?
  • 好像你要返回 state.pages 两次:(1st)...state, pages: [(2nd)...state.pages

标签: javascript reactjs ecmascript-6 redux react-redux


【解决方案1】:

这是过滤重复项的“智能”方法。

function filterDuplicates(array, areEqual) {
  return array.filter((item, pos) => {
    return array.findIndex((other) => areEqual(item, other)) == pos;
  });
}

console.log(
  filterDuplicates([
    { key: 1, name: 'test' },
    { key: 2, name: 'apple' },
    { key: 1, name: 'test' },
  ], (a, b) => a.key == b.key)
);

将数组传递给filterDuplicates 的第一个参数,将相等比较器传递给第二个参数。我从that answer 得到这个想法。

打字稿

function filterDuplicates<T>(array: T[], areEqual: ((a: T, b: T) => boolean)): T[] {
  return array.filter((item: T, pos: number) => {
    return array.findIndex((other: T) => areEqual(item, other)) == pos;
  });
}

【讨论】:

    【解决方案2】:

    你可以这样做:

    检查您所在州是否存在现有页面,是否返回相同或推送

    case LOAD_PAGES:
            return {
                ...state,
                pages: state.pages.findIndex(page => page.key === action.pages.key) >= 0 ?
                        state.pages :
                        [...state.pages, action.pages]
            };
    

    【讨论】:

    • 你可以使用内置数组函数some,而不是使用findIndex
    • @NikitaMalyschkin,findIndex() 方法返回数组中第一个满足提供的测试函数的元素的索引,所以没有额外的循环,我们可以保持原样
    • @VivelDoshi,some() 方法也是如此。 findIndex 在任何方面都没有错,但 some 正是完成这项工作的合适工具。
    • @NikitaMalyschkin,是的,你可以这么说。
    【解决方案3】:

    有很多方法可以解决您的问题,以下是我的解决方法:

    不要使用数组,而是将页面存储在对象中,并使用已经定义的键作为对象的键。您可以像以前一样使用Object.values(store.pages)Object.entries(store.pages) 获取页面数组。

    【讨论】:

      【解决方案4】:

      只需使用set,重复的元素就可以省略。

      return { ...state, arr: Array.from(new Set([...state.arr, ...newArr]))};
      

      【讨论】:

        猜你喜欢
        • 2020-04-13
        • 2017-03-16
        • 2019-03-13
        • 2020-03-10
        • 2020-05-09
        • 1970-01-01
        • 2020-04-06
        • 1970-01-01
        • 2012-03-28
        相关资源
        最近更新 更多