← Усі задачіReact · Senior

Стабільний колбек

Напишіть хук useStableCallback(callback). Він повертає функцію, яка лишається тією самою на всіх рендерах, але під час виклику завжди виконує останню версію callback - з актуальними пропсами й станом - і повертає її результат.

Таку функцію можна покласти в залежності ефекту або передати в memo-компонент, не перезапускаючи ефект і не ламаючи мемоізацію.

Тести (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']);