1

I am doing this:

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

And I have a component that every time I enter to it, it send the same data to the store so I am getting lots of duplicate data.

The pages array looks like this:

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

This is the React component:

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

Any ideas?

Non
  • 8,409
  • 20
  • 71
  • 123

4 Answers4

3

Here's "smart" way to filter duplicates.

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

Pass array to first argument and equality comparer to second argument of filterDuplicates. I got this idea from that answer.

TypeScript

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;
  });
}
TheMisir
  • 4,083
  • 1
  • 27
  • 37
2

You can do something like this :

Check if there is an existing page in your state or not, if return same or else push

case LOAD_PAGES:
        return {
            ...state,
            pages: state.pages.findIndex(page => page.key === action.pages.key) >= 0 ?
                    state.pages :
                    [...state.pages, action.pages]
        };
Vivek Doshi
  • 56,649
  • 12
  • 110
  • 122
1

There are many ways to solve your problem and here is how I would approach it:

Instead of using an array, store your pages in an object and use the already defined keys as keys for the object. You can use Object.values(store.pages) or Object.entries(store.pages) to get an array of the pages the way you did before.

1

Simply using set, the duplicated element can be omitted.

return { ...state, arr: Array.from(new Set([...state.arr, ...newArr]))};
Milos Rad
  • 49
  • 1
  • 3