Skip to content

Commit

Permalink
Split out useIsMountedRef hook
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Aug 24, 2023
1 parent 1d22858 commit af1fba9
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/react-hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export { default as usePrevious } from './usePrevious';
export { default as useForwardedRef } from './useForwardedRef';
export { default as useCopyToClipboard } from './useCopyToClipboard';
export { default as useFormWithDetachedSubmitButton } from './useFormWithDetachedSubmitButton';
export * from './useIsMountedRef';
export { default as usePromiseFactory } from './usePromiseFactory';
export type { UseFormWithDetachedSubmitButtonResult } from './useFormWithDetachedSubmitButton';
export type {
Expand Down
8 changes: 4 additions & 4 deletions packages/react-hooks/src/useAsyncInterval.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useRef } from 'react';
import Log from '@deephaven/log';
import { useIsMountedRef } from './useIsMountedRef';

const log = Log.module('useAsyncInterval');

Expand All @@ -24,7 +25,7 @@ export function useAsyncInterval(
callback: () => Promise<void>,
targetIntervalMs: number
) {
const isCancelledRef = useRef(false);
const isMountedRef = useIsMountedRef();
const trackingRef = useRef({ count: 0, started: Date.now() });
const setTimeoutRef = useRef(0);

Expand All @@ -43,7 +44,7 @@ export function useAsyncInterval(

await callback();

if (isCancelledRef.current) {
if (!isMountedRef.current) {
return;
}

Expand All @@ -61,15 +62,14 @@ export function useAsyncInterval(
log.debug('adjusted minIntervalMs:', nextTickInterval);

setTimeoutRef.current = window.setTimeout(tick, nextTickInterval);
}, [callback, targetIntervalMs]);
}, [callback, isMountedRef, targetIntervalMs]);

useEffect(() => {
log.debug('Setting interval minIntervalMs:', targetIntervalMs);

setTimeoutRef.current = window.setTimeout(tick, targetIntervalMs);

return () => {
isCancelledRef.current = true;
window.clearTimeout(setTimeoutRef.current);
};
}, [targetIntervalMs, tick]);
Expand Down
19 changes: 19 additions & 0 deletions packages/react-hooks/src/useIsMountedRef.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { renderHook } from '@testing-library/react-hooks';
import { useIsMountedRef } from './useIsMountedRef';

beforeEach(() => {
jest.clearAllMocks();
expect.hasAssertions();
});

describe('useIsMountedRef', () => {
it('should return a ref which tracks whether the component is mounted or not', () => {
const { result, unmount } = renderHook(() => useIsMountedRef());

expect(result.current.current).toBe(true);

unmount();

expect(result.current.current).toBe(false);
});
});
20 changes: 20 additions & 0 deletions packages/react-hooks/src/useIsMountedRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect, useRef } from 'react';

/**
* Returns a ref which tracks whether the component is mounted or not.
*/
export function useIsMountedRef() {
const isMountedRef = useRef(false);

useEffect(() => {
isMountedRef.current = true;

return () => {
isMountedRef.current = false;
};
}, []);

return isMountedRef;
}

export default useIsMountedRef;

0 comments on commit af1fba9

Please sign in to comment.