← All tasksReact · Senior
useInterval hook
Write a useInterval(callback, delay) hook that calls callback every delay milliseconds while the component is mounted.
Each call must use the latest version of callback with current props and state, but a new function on every render must not restart the interval. delay = null pauses the interval. After unmounting there are no more calls.
Ctrl+Enter runs the tests. Tab indents; to leave the editor with the keyboard, press Esc and then Tab. Your code is saved in this browser.
Tests (5)
const f = fn(); renderHook(() => useInterval(f, 30)); await wait(110); expect(f.calls.length >= 2 && f.calls.length <= 4).toBe(true);
const log = []; const { rerender } = renderHook(({ n }) => useInterval(() => log.push(n), 30), { initialProps: { n: 1 } }); await wait(45); rerender({ n: 2 }); await wait(50); expect(log[0]).toBe(1); expect(log[log.length - 1]).toBe(2);
const f = fn(); const { rerender } = renderHook(() => useInterval(() => f(), 40)); for (let i = 0; i < 6; i++) { await wait(15); rerender(); } expect(f.calls.length >= 1).toBe(true);
const f = fn(); renderHook(() => useInterval(f, null)); await wait(60); expect(f).toHaveBeenCalledTimes(0);
const f = fn(); const { unmount } = renderHook(() => useInterval(f, 20)); unmount(); await wait(60); expect(f).toHaveBeenCalledTimes(0);