All files / src/componentsV2/Table/hooks useIterator.ts

18.91% Statements 7/37
0% Branches 0/34
33.33% Functions 2/6
18.91% Lines 7/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103    28x             1004x   1004x                                                                                                   1004x           20x 20x                                                 1004x                  
import { useState } from "react";
 
const useIterator = ({
  dataLen,
  rowsPerPage,
}: {
  dataLen: number;
  rowsPerPage: number;
}) => {
  const [selectedRowIdx, setSelectedRowIdx] = useState<number>(-1);
 
  const onChangeSelectedRowItem = (
    newIdx: number | string,
    currentPage = 1,
    isOldList = false,
  ) => {
    setSelectedRowIdx((current: number) => {
      if (typeof newIdx === "number") {
        return newIdx;
      } else {
        const a = {
          next: 1,
          prev: -1,
        };
 
        const idx = current + a[newIdx as "next" | "prev"];
 
        if (isOldList) {
          if (newIdx === "prev") {
            if (currentPage > 1) {
              if (current === 0) {
                return rowsPerPage - 1;
              }
            } else {
              /*
            If the current page is 1:
             - if is selected the first item of the list and prev is pressed, do nothing          
          */
              if (current === 0) {
                return 0;
              }
            }
          }
 
          if (idx >= rowsPerPage) {
            return 0;
          }
 
          if (newIdx === "next") {
            //if there is not more data just do nothing
            if (idx > rowsPerPage) {
              return current;
            }
          }
        }
 
        return idx;
      }
    });
  };
 
  const onIterator = (setPage: any, currentPage: number, useOldList = true) => {
    /*
    The variable local is introduced to capture the value of selectedRowIdx at the time the function is invoked. This is done because relying directly on selectedRowIdx inside the setPage callback can lead to stale state issues due to React's asynchronous state updates.
    React state updates are asynchronous, meaning that the value of selectedRowIdx might not reflect the latest state when accessed inside a callback like setPage. If you rely directly on selectedRowIdx, you risk using an outdated value, 
    especially when multiple state updates occur in quick succession.
    */
    let local = selectedRowIdx;
    return (newIdx: number | string) => {
      setPage((current: number) => {
        if (!useOldList) {
          const index = local + 1;
          return Math.ceil(index / rowsPerPage) ?? 1;
        }
        /*
                If the current page is greater than 1:
                 - if is selected the first item of the list and prev is pressed, go to previous page and return the index of the last item on the new page
          */
        if (current > 1 && local === 0 && newIdx === "prev") {
          local = rowsPerPage - 1;
          return current - 1;
        }
 
        if (local + 1 >= rowsPerPage && newIdx === "next") {
          local = 0;
          return current + 1;
        }
 
        return current;
      });
      onChangeSelectedRowItem(newIdx, currentPage, useOldList);
    };
  };
  return {
    setSelectedRowIdx,
    onIterator,
    onChangeSelectedRowItem,
    selectedRowIdx,
  };
};
 
export default useIterator;