Skip to content

Commit

Permalink
fix(VirtualTable): optimise requests (#676)
Browse files Browse the repository at this point in the history
  • Loading branch information
artemmufazalov authored Feb 1, 2024
1 parent 904ea08 commit 9a50a34
Showing 1 changed file with 27 additions and 17 deletions.
44 changes: 27 additions & 17 deletions src/components/VirtualTable/VirtualTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const VirtualTable = <T,>({

const [error, setError] = useState<IResponseError>();

const [pendingRequests, setPendingRequests] = useState<Record<string, NodeJS.Timeout>>({});
const pendingRequests = useRef<Record<string, ReturnType<typeof setTimeout>>>({});

const fetchChunkData = useCallback(
async (id: string) => {
Expand Down Expand Up @@ -105,10 +105,13 @@ export const VirtualTable = <T,>({
}
}, DEFAULT_REQUEST_TIMEOUT);

setPendingRequests((reqs) => {
reqs[id] = timer;
return reqs;
});
// Chunk data load could be triggered by different events
// Cancel previous chunk request, while it is pending (instead of concurrentId)
if (pendingRequests.current[id]) {
const oldTimer = pendingRequests.current[id];
window.clearTimeout(oldTimer);
}
pendingRequests.current[id] = timer;
},
[fetchData, limit, sortParams],
);
Expand All @@ -117,20 +120,27 @@ export const VirtualTable = <T,>({
dispatch(initChunk(id));
}, []);

const onLeave = useCallback<OnLeave>(
(id) => {
dispatch(removeChunk(id));
const onLeave = useCallback<OnLeave>((id) => {
dispatch(removeChunk(id));

// If there is a pending request for the removed chunk, cancel it
// It made to prevent excessive requests on fast scroll
if (pendingRequests.current[id]) {
const timer = pendingRequests.current[id];
window.clearTimeout(timer);
delete pendingRequests.current[id];
}
}, []);

// If there is a pending request for the removed chunk, cancel it
// It made to prevent excessive requests on fast scroll
if (pendingRequests[id]) {
const timer = pendingRequests[id];
// Cancel all pending requests on component unmount
useEffect(() => {
return () => {
Object.values(pendingRequests.current).forEach((timer) => {
window.clearTimeout(timer);
delete pendingRequests[id];
}
},
[pendingRequests],
);
});
pendingRequests.current = {};
};
}, []);

// Load chunks if they become active
// This mecanism helps to set chunk active state from different sources, but load data only once
Expand Down

0 comments on commit 9a50a34

Please sign in to comment.