Skip to content

Commit 9a50a34

Browse files
fix(VirtualTable): optimise requests (#676)
1 parent 904ea08 commit 9a50a34

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

src/components/VirtualTable/VirtualTable.tsx

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const VirtualTable = <T,>({
7676

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

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

8181
const fetchChunkData = useCallback(
8282
async (id: string) => {
@@ -105,10 +105,13 @@ export const VirtualTable = <T,>({
105105
}
106106
}, DEFAULT_REQUEST_TIMEOUT);
107107

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

120-
const onLeave = useCallback<OnLeave>(
121-
(id) => {
122-
dispatch(removeChunk(id));
123+
const onLeave = useCallback<OnLeave>((id) => {
124+
dispatch(removeChunk(id));
125+
126+
// If there is a pending request for the removed chunk, cancel it
127+
// It made to prevent excessive requests on fast scroll
128+
if (pendingRequests.current[id]) {
129+
const timer = pendingRequests.current[id];
130+
window.clearTimeout(timer);
131+
delete pendingRequests.current[id];
132+
}
133+
}, []);
123134

124-
// If there is a pending request for the removed chunk, cancel it
125-
// It made to prevent excessive requests on fast scroll
126-
if (pendingRequests[id]) {
127-
const timer = pendingRequests[id];
135+
// Cancel all pending requests on component unmount
136+
useEffect(() => {
137+
return () => {
138+
Object.values(pendingRequests.current).forEach((timer) => {
128139
window.clearTimeout(timer);
129-
delete pendingRequests[id];
130-
}
131-
},
132-
[pendingRequests],
133-
);
140+
});
141+
pendingRequests.current = {};
142+
};
143+
}, []);
134144

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

0 commit comments

Comments
 (0)