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