diff --git a/.changeset/thin-beans-cry.md b/.changeset/thin-beans-cry.md new file mode 100644 index 000000000..53b6f9783 --- /dev/null +++ b/.changeset/thin-beans-cry.md @@ -0,0 +1,5 @@ +--- +"@scaleway/use-dataloader": minor +--- + +Fix : Ensure observers are correctly added at mount to handle components mount/unmount quick chaining diff --git a/packages/use-dataloader/src/useInfiniteDataLoader.ts b/packages/use-dataloader/src/useInfiniteDataLoader.ts index 180d0a331..f1b41271d 100644 --- a/packages/use-dataloader/src/useInfiniteDataLoader.ts +++ b/packages/use-dataloader/src/useInfiniteDataLoader.ts @@ -73,20 +73,25 @@ export const useInfiniteDataLoader = < const [, setCounter] = useState(0) - const forceRerender = useCallback(() => { + const forceRerender = useRef(() => { setCounter(current => current + 1) - }, []) + }) const baseQueryKey = useMemo(() => marshalQueryKey(baseKey), [baseKey]) - useEffect( - () => () => { - requestRefs.current.forEach(request => - request.removeObserver(forceRerender), - ) - }, - [forceRerender], - ) + useEffect(() => { + const notifyFn = forceRerender.current + // Ensure observers are added after first mount + requestRefs.current.forEach(request => + !request.observers.includes(notifyFn) + ? request.addObserver(notifyFn) + : undefined, + ) + + return () => { + requestRefs.current.forEach(request => request.removeObserver(notifyFn)) + } + }, []) const getCurrentRequest = () => { const currentQueryKey = marshalQueryKey([ @@ -94,14 +99,15 @@ export const useInfiniteDataLoader = < 'infinite', page as string | number, ]) - requestRefs.current.forEach(request => - !request.key.startsWith(computeKey(baseQueryKey)) - ? request.removeObserver(forceRerender) - : undefined, - ) - requestRefs.current = requestRefs.current.filter(({ key }) => - key.startsWith(computeKey(baseQueryKey)), - ) + // 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), ) @@ -110,8 +116,10 @@ export const useInfiniteDataLoader = < enabled, method: getMethodRef.current, }) + if (!request.observers.includes(forceRerender.current)) { + request.addObserver(forceRerender.current) + } requestRefs.current.push(request) - request.addObserver(forceRerender) return request }