Skip to content

Instantly share code, notes, and snippets.

@osbornm
Created April 7, 2021 15:45
Show Gist options
  • Save osbornm/223b3056dda2e76861e4be1fd1ca36e9 to your computer and use it in GitHub Desktop.
Save osbornm/223b3056dda2e76861e4be1fd1ca36e9 to your computer and use it in GitHub Desktop.
React: useInterval
import { renderHook } from '@testing-library/react-hooks';
import useInterval from './useInterval';
describe('useInterval', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
});
it('should run the callback after the delay', () => {
const cb = jest.fn();
renderHook(() => useInterval(cb, 5000));
expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 5000);
expect(cb).not.toHaveBeenCalled();
jest.runOnlyPendingTimers();
expect(cb).toHaveBeenCalledTimes(1);
jest.runOnlyPendingTimers();
expect(cb).toHaveBeenCalledTimes(2);
});
it('clears interval when unmounted', () => {
const cb = jest.fn();
const delay = 5000;
const { unmount } = renderHook(() => useInterval(cb, delay));
unmount();
expect(clearInterval).toHaveBeenCalled();
jest.runOnlyPendingTimers();
expect(cb).not.toHaveBeenCalled();
});
it('has a default value for delay', () => {
const cb = jest.fn();
renderHook(() => useInterval(cb));
expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 30000);
expect(cb).not.toHaveBeenCalled();
jest.runOnlyPendingTimers();
expect(cb).toHaveBeenCalledTimes(1);
});
});
import { useEffect, useRef } from 'react';
function useInterval(callback: Function, delay = 30000) {
const savedCallback = useRef<Function>();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
if (savedCallback.current)
savedCallback.current();
}
if (delay !== null) {
const id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
export default useInterval;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment