From 56abab8349d6f70e70902466aee9dd47d5bf3168 Mon Sep 17 00:00:00 2001 From: mufazalov Date: Tue, 30 Jan 2024 19:06:02 +0300 Subject: [PATCH 1/2] fix(VirtualTable): optimise requests --- src/components/VirtualTable/VirtualTable.tsx | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/VirtualTable/VirtualTable.tsx b/src/components/VirtualTable/VirtualTable.tsx index 09d0cf0361..c16e50497c 100644 --- a/src/components/VirtualTable/VirtualTable.tsx +++ b/src/components/VirtualTable/VirtualTable.tsx @@ -76,7 +76,7 @@ export const VirtualTable = ({ const [error, setError] = useState(); - const [pendingRequests, setPendingRequests] = useState>({}); + const pendingRequests = useRef>>({}); const fetchChunkData = useCallback( async (id: string) => { @@ -105,10 +105,13 @@ export const VirtualTable = ({ } }, 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], ); @@ -117,20 +120,17 @@ export const VirtualTable = ({ dispatch(initChunk(id)); }, []); - const onLeave = useCallback( - (id) => { - dispatch(removeChunk(id)); + const onLeave = useCallback((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[id]) { - const timer = pendingRequests[id]; - window.clearTimeout(timer); - delete pendingRequests[id]; - } - }, - [pendingRequests], - ); + // 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]; + } + }, []); // Load chunks if they become active // This mecanism helps to set chunk active state from different sources, but load data only once From ae0810636fcf01f9154ae6901b789cc9a6f89476 Mon Sep 17 00:00:00 2001 From: mufazalov Date: Thu, 1 Feb 2024 12:20:18 +0300 Subject: [PATCH 2/2] fix(VirtualTable): cancel pending requests on component unmount --- src/components/VirtualTable/VirtualTable.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/VirtualTable/VirtualTable.tsx b/src/components/VirtualTable/VirtualTable.tsx index c16e50497c..d360dd42ba 100644 --- a/src/components/VirtualTable/VirtualTable.tsx +++ b/src/components/VirtualTable/VirtualTable.tsx @@ -132,6 +132,16 @@ export const VirtualTable = ({ } }, []); + // Cancel all pending requests on component unmount + useEffect(() => { + return () => { + Object.values(pendingRequests.current).forEach((timer) => { + window.clearTimeout(timer); + }); + pendingRequests.current = {}; + }; + }, []); + // Load chunks if they become active // This mecanism helps to set chunk active state from different sources, but load data only once // Only currently active chunks should be in state so iteration by the whole state shouldn't be a problem