From 56020c82857bcb8a698eb7f1e5cdd5bcc1e15742 Mon Sep 17 00:00:00 2001 From: Dorian Maliszewski Date: Tue, 24 May 2022 12:28:59 +0200 Subject: [PATCH] feat: use interval instead of timeout --- .../src/__tests__/useDataLoader.test.tsx | 8 +-- packages/use-dataloader/src/useDataLoader.ts | 57 +++++++------------ 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx b/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx index dbc01bfac..927163d35 100644 --- a/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx +++ b/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx @@ -251,7 +251,7 @@ describe('useDataLoader', () => { const pollingProps = { config: { needPolling: () => true, - pollingInterval: PROMISE_TIMEOUT, + pollingInterval: 1000, }, key: 'test-6', method: jest.fn( @@ -295,7 +295,7 @@ describe('useDataLoader', () => { rerender({ ...pollingProps, config: { - pollingInterval: 300, + pollingInterval: 1000, }, method: method2, }) @@ -314,7 +314,7 @@ describe('useDataLoader', () => { rerender({ ...pollingProps, config: { - pollingInterval: PROMISE_TIMEOUT, + pollingInterval: 1000, }, method: method2, }) @@ -363,7 +363,7 @@ describe('useDataLoader', () => { const pollingProps = { config: { needPolling: true, - pollingInterval: PROMISE_TIMEOUT, + pollingInterval: 1000, }, key: 'test-needpolling-no-interval', method: jest.fn( diff --git a/packages/use-dataloader/src/useDataLoader.ts b/packages/use-dataloader/src/useDataLoader.ts index bcf332cb8..545cf810f 100644 --- a/packages/use-dataloader/src/useDataLoader.ts +++ b/packages/use-dataloader/src/useDataLoader.ts @@ -1,10 +1,4 @@ -import { - useCallback, - useEffect, - useLayoutEffect, - useRef, - useState, -} from 'react' +import { useCallback, useEffect, useRef, useState } from 'react' import { useDataLoaderContext } from './DataLoaderProvider' import { StatusEnum } from './constants' import DataLoader from './dataloader' @@ -27,20 +21,12 @@ function useDataLoader( const methodRef = useRef(method) const onSuccessRef = useRef(onSuccess) const onErrorRef = useRef(onError ?? onGlobalError) - const isMountedRef = useRef(false) + const needPollingRef = useRef(needPolling) const [, setCounter] = useState(0) const forceRerender = useCallback(() => { setCounter(current => current + 1) }, []) - useLayoutEffect(() => { - isMountedRef.current = true - - return () => { - isMountedRef.current = false - } - }) - const request = getOrAddRequest(fetchKey, { enabled, method: methodRef.current, @@ -77,6 +63,10 @@ function useDataLoader( [request], ) + useEffect(() => { + needPollingRef.current = needPolling + }, [needPolling]) + useEffect(() => { request.method = method }, [method, request]) @@ -102,33 +92,30 @@ function useDataLoader( }, [enabled, request, keepPreviousData]) useEffect(() => { - let timeout: NodeJS.Timeout - - if ( - isMountedRef.current && - request && - pollingInterval && - needPolling && - (request.status === StatusEnum.SUCCESS || - request.status === StatusEnum.ERROR) - ) { - if ( - (typeof needPolling === 'function' && needPolling(request.data)) || - (typeof needPolling !== 'function' && needPolling) - ) { - timeout = setTimeout(() => { + let interval: NodeJS.Timer + + if (pollingInterval) { + interval = setInterval(() => { + if ( + (needPollingRef.current && + typeof needPollingRef.current === 'function' && + needPollingRef.current(request.data)) || + (typeof needPollingRef.current !== 'function' && + needPollingRef.current && + !request.isCalled) + ) { request .load(true) .then(onSuccessRef.current) .catch(onErrorRef.current) - }, pollingInterval) - } + } + }, pollingInterval) } return () => { - if (timeout && !isMountedRef.current) clearTimeout(timeout) + if (interval) clearInterval(interval) } - }, [pollingInterval, needPolling, request, request.status, request.data]) + }, [pollingInterval, request]) return { data: !request.isFirstLoading ? request.data : initialData,