← Alle AufgabenReact · Senior

Hook useInterval

Schreib einen Hook useInterval(callback, delay), der callback alle delay Millisekunden aufruft, solange die Komponente gemountet ist.

Jeder Aufruf muss die neueste Version von callback mit aktuellen Props und State nutzen, aber eine neue Funktion bei jedem Render darf das Intervall nicht neu starten. delay = null pausiert das Intervall. Nach dem Aushängen gibt es keine Aufrufe mehr.

Tests (5)

  1. const f = fn();
    renderHook(() => useInterval(f, 30));
    await wait(110);
    expect(f.calls.length >= 2 && f.calls.length <= 4).toBe(true);
  2. 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);
  3. 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);
  4. const f = fn();
    renderHook(() => useInterval(f, null));
    await wait(60);
    expect(f).toHaveBeenCalledTimes(0);
  5. const f = fn();
    const { unmount } = renderHook(() => useInterval(f, 20));
    unmount();
    await wait(60);
    expect(f).toHaveBeenCalledTimes(0);