← Alle AufgabenReact · Senior

Stabiler Callback

Schreib einen Hook useStableCallback(callback). Er liefert eine Funktion, die über alle Renders gleich bleibt, beim Aufruf aber immer die neueste Version von callback ausführt, mit aktuellen Props und State, und deren Ergebnis liefert.

Eine solche Funktion kann in die Abhängigkeiten eines Effects oder an eine memo-Komponente gehen, ohne den Effect neu zu starten oder die Memoisierung zu brechen.

Tests (4)

  1. const { result, rerender } = renderHook(({ n }) => useStableCallback(() => n), { initialProps: { n: 1 } });
    const first = result.current;
    rerender({ n: 2 });
    rerender({ n: 3 });
    expect(result.current).toBe(first);
  2. const { result, rerender } = renderHook(({ n }) => useStableCallback(() => n), { initialProps: { n: 1 } });
    expect(result.current()).toBe(1);
    rerender({ n: 2 });
    expect(result.current()).toBe(2);
  3. const { result } = renderHook(() => useStableCallback((a, b) => a + b));
    expect(result.current(2, 3)).toBe(5);
  4. const seen = [];
    function Child({ onSave }) {
      useEffect(() => {
        seen.push('effect');
      }, [onSave]);
      return null;
    }
    function Parent({ value }) {
      const onSave = useStableCallback(() => value);
      return <Child onSave={onSave} />;
    }
    const { rerender } = render(<Parent value="a" />);
    rerender(<Parent value="b" />);
    rerender(<Parent value="c" />);
    expect(seen).toEqual(['effect']);