From a6ef6be989b11fbdfedd6fd0a73a07f4db9b4c52 Mon Sep 17 00:00:00 2001 From: Levende Date: Wed, 15 Oct 2025 15:44:57 +0200 Subject: [PATCH 1/3] fix: bug on infinity dataloader --- .changeset/spotty-words-flow.md | 5 +++ .../fuzzy-search/src/__tests__/index.test.tsx | 2 +- .../src/useInfiniteDataLoader.ts | 40 +++++++++---------- 3 files changed, 25 insertions(+), 22 deletions(-) create mode 100644 .changeset/spotty-words-flow.md diff --git a/.changeset/spotty-words-flow.md b/.changeset/spotty-words-flow.md new file mode 100644 index 000000000..61a3fa0d1 --- /dev/null +++ b/.changeset/spotty-words-flow.md @@ -0,0 +1,5 @@ +--- +"@scaleway/use-dataloader": patch +--- + +Fix bug on infinity data loader diff --git a/packages/fuzzy-search/src/__tests__/index.test.tsx b/packages/fuzzy-search/src/__tests__/index.test.tsx index 99b28105d..c69437771 100644 --- a/packages/fuzzy-search/src/__tests__/index.test.tsx +++ b/packages/fuzzy-search/src/__tests__/index.test.tsx @@ -1,5 +1,5 @@ import { describe, expect, test } from 'vitest' -import { isFuzzyMatch, levenshteinDistance, normalizeString } from ".." +import { isFuzzyMatch, levenshteinDistance, normalizeString } from '..' describe('fuzzySearch', () => { describe('normalizeString', () => { diff --git a/packages/use-dataloader/src/useInfiniteDataLoader.ts b/packages/use-dataloader/src/useInfiniteDataLoader.ts index 9956af472..49770b8d8 100644 --- a/packages/use-dataloader/src/useInfiniteDataLoader.ts +++ b/packages/use-dataloader/src/useInfiniteDataLoader.ts @@ -55,13 +55,15 @@ export const useInfiniteDataLoader = < getNextPage ? getNextPage(...params) : undefined, ) - const paramsRef = useRef({ - ...baseParams, - [pageParamKey]: page, - }) - - const getMethodRef = useRef(() => method(paramsRef.current)) + const paramsMemo = useMemo( + () => ({ + ...baseParams, + [pageParamKey]: page, + }), + [baseParams, page, pageParamKey], + ) + const getMethodRef = useRef(() => method(paramsMemo)) const getOnSuccessRef = useRef( (...params: Parameters>) => onSuccess?.(...params), @@ -99,23 +101,28 @@ export const useInfiniteDataLoader = < 'infinite', page as string | number, ]) + // Clean bad requests in the array requestRefs.current = requestRefs.current.filter(request => { if (request.key.startsWith(computeKey(baseQueryKey))) { return true } + request.removeObserver(forceRerender.current) return false }) + const requestInRef = requestRefs.current.find(request => request.key.endsWith(currentQueryKey), ) + if (!requestInRef) { const request = getOrAddRequest(currentQueryKey, { enabled, method: getMethodRef.current, }) + if (!request.observers.includes(forceRerender.current)) { request.addObserver(forceRerender.current) } @@ -176,17 +183,13 @@ export const useInfiniteDataLoader = < const loadMoreRef = useRef(() => { if (nextPageRef.current) { - paramsRef.current = { - ...baseParams, - [pageParamKey]: nextPageRef.current, - } setPage(curr => nextPageRef.current ?? curr) } }) useEffect(() => { - request.method = () => method(paramsRef.current) - }, [method, request]) + request.method = () => method(paramsMemo) + }, [method, request, paramsMemo]) useEffect(() => { if (keepPreviousData) { @@ -210,28 +213,23 @@ export const useInfiniteDataLoader = < .then(async result => { nextPageRef.current = getNextPageFnRef.current( result, - paramsRef.current, + paramsMemo, ) as typeof page await onSuccessLoad(result) }) .catch(onFailedLoad) } optimisticIsLoadingRef.current = false - }, [needLoad, request]) + }, [needLoad, request, paramsMemo]) - useEffect(() => { - paramsRef.current = { - ...baseParams, - [pageParamKey]: page, - } - /* eslint-disable-next-line react-hooks/exhaustive-deps */ - }, [baseParams, pageParamKey]) useEffect(() => { getOnSuccessRef.current = (...params) => onSuccess?.(...params) }, [onSuccess]) + useEffect(() => { getOnErrorRef.current = err => onError?.(err) ?? onGlobalError?.(err) }, [onError, onGlobalError]) + useEffect(() => { getNextPageFnRef.current = (...params) => getNextPage ? getNextPage(...params) : undefined From ae89fc2c2d768816def2124ec9a7e203ae6a9899 Mon Sep 17 00:00:00 2001 From: Levende Date: Thu, 16 Oct 2025 10:56:57 +0200 Subject: [PATCH 2/3] fix: bug on infinity dataloader --- .../src/useInfiniteDataLoader.ts | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/use-dataloader/src/useInfiniteDataLoader.ts b/packages/use-dataloader/src/useInfiniteDataLoader.ts index 49770b8d8..d5a592c8e 100644 --- a/packages/use-dataloader/src/useInfiniteDataLoader.ts +++ b/packages/use-dataloader/src/useInfiniteDataLoader.ts @@ -55,15 +55,17 @@ export const useInfiniteDataLoader = < getNextPage ? getNextPage(...params) : undefined, ) - const paramsMemo = useMemo( - () => ({ - ...baseParams, - [pageParamKey]: page, - }), - [baseParams, page, pageParamKey], - ) + const paramsRef = useRef({ + ...baseParams, + [pageParamKey]: page, + }) + + paramsRef.current = { + ...baseParams, + [pageParamKey]: page, + } - const getMethodRef = useRef(() => method(paramsMemo)) + const getMethodRef = useRef(() => method(paramsRef.current)) const getOnSuccessRef = useRef( (...params: Parameters>) => onSuccess?.(...params), @@ -188,8 +190,8 @@ export const useInfiniteDataLoader = < }) useEffect(() => { - request.method = () => method(paramsMemo) - }, [method, request, paramsMemo]) + request.method = () => method(paramsRef.current) + }, [method, request]) useEffect(() => { if (keepPreviousData) { @@ -213,14 +215,14 @@ export const useInfiniteDataLoader = < .then(async result => { nextPageRef.current = getNextPageFnRef.current( result, - paramsMemo, + paramsRef.current, ) as typeof page await onSuccessLoad(result) }) .catch(onFailedLoad) } optimisticIsLoadingRef.current = false - }, [needLoad, request, paramsMemo]) + }, [needLoad, request]) useEffect(() => { getOnSuccessRef.current = (...params) => onSuccess?.(...params) From 00590506364ba20719db20562b1f0feea93270d5 Mon Sep 17 00:00:00 2001 From: Levende Date: Thu, 16 Oct 2025 14:43:33 +0200 Subject: [PATCH 3/3] fix: bug on infinity dataloader --- .../use-dataloader/src/useInfiniteDataLoader.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/use-dataloader/src/useInfiniteDataLoader.ts b/packages/use-dataloader/src/useInfiniteDataLoader.ts index d5a592c8e..86bd5aa3d 100644 --- a/packages/use-dataloader/src/useInfiniteDataLoader.ts +++ b/packages/use-dataloader/src/useInfiniteDataLoader.ts @@ -55,17 +55,12 @@ export const useInfiniteDataLoader = < getNextPage ? getNextPage(...params) : undefined, ) - const paramsRef = useRef({ - ...baseParams, - [pageParamKey]: page, - }) - - paramsRef.current = { + const paramsArgs = { ...baseParams, [pageParamKey]: page, } - const getMethodRef = useRef(() => method(paramsRef.current)) + const getMethodRef = useRef(() => method(paramsArgs)) const getOnSuccessRef = useRef( (...params: Parameters>) => onSuccess?.(...params), @@ -190,7 +185,8 @@ export const useInfiniteDataLoader = < }) useEffect(() => { - request.method = () => method(paramsRef.current) + request.method = () => method(paramsArgs) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [method, request]) useEffect(() => { @@ -215,13 +211,14 @@ export const useInfiniteDataLoader = < .then(async result => { nextPageRef.current = getNextPageFnRef.current( result, - paramsRef.current, + paramsArgs, ) as typeof page await onSuccessLoad(result) }) .catch(onFailedLoad) } optimisticIsLoadingRef.current = false + // eslint-disable-next-line react-hooks/exhaustive-deps }, [needLoad, request]) useEffect(() => {