← All tasksReact · Middle

useDebounce hook

Write a useDebounce(value, ms) hook. It returns value, but delayed: a new value only shows up once value hasn't changed for ms milliseconds. Every change restarts the countdown.

On the first render the hook returns the initial value right away. After unmounting, the pending update must not fire.

Tests (4)

  1. const { result } = renderHook(({ v }) => useDebounce(v, 50), { initialProps: { v: 'a' } });
    expect(result.current).toBe('a');
  2. const { result, rerender } = renderHook(({ v }) => useDebounce(v, 50), { initialProps: { v: 'a' } });
    rerender({ v: 'ab' });
    expect(result.current).toBe('a');
    await wait(90);
    expect(result.current).toBe('ab');
  3. const { result, rerender } = renderHook(({ v }) => useDebounce(v, 60), { initialProps: { v: 'a' } });
    rerender({ v: 'b' });
    await wait(30);
    rerender({ v: 'c' });
    await wait(40);
    expect(result.current).toBe('a');
    await wait(60);
    expect(result.current).toBe('c');
  4. const { result, rerender, unmount } = renderHook(({ v }) => useDebounce(v, 30), { initialProps: { v: 1 } });
    rerender({ v: 2 });
    unmount();
    await wait(60);
    expect(result.current).toBe(1);