← Alle AufgabenReact · Senior

Rückgängig und Wiederholen

Schreib einen Hook useHistory(initial): State mit Änderungsverlauf. Er liefert { value, set, undo, redo, canUndo, canRedo }.

set(v) macht v zum aktuellen Wert und merkt sich den vorigen. undo() holt den vorigen Wert zurück, redo() den rückgängig gemachten. Ein neues set nach undo verwirft den Redo-Zweig. undo und redo tun ohne Verlauf nichts. Mehrere set-Aufrufe hintereinander in einem Handler müssen alle festgehalten werden.

Tests (6)

  1. const { result } = renderHook(() => useHistory('a'));
    expect(result.current.value).toBe('a');
    expect(result.current.canUndo).toBe(false);
    expect(result.current.canRedo).toBe(false);
  2. const { result } = renderHook(() => useHistory(0));
    act(() => result.current.set(1));
    act(() => result.current.set(2));
    act(() => result.current.undo());
    expect(result.current.value).toBe(1);
    act(() => result.current.undo());
    expect(result.current.value).toBe(0);
    expect(result.current.canUndo).toBe(false);
  3. const { result } = renderHook(() => useHistory(0));
    act(() => result.current.set(1));
    act(() => result.current.undo());
    expect(result.current.canRedo).toBe(true);
    act(() => result.current.redo());
    expect(result.current.value).toBe(1);
    expect(result.current.canRedo).toBe(false);
  4. const { result } = renderHook(() => useHistory(0));
    act(() => result.current.set(1));
    act(() => result.current.set(2));
    act(() => result.current.undo());
    act(() => result.current.set(3));
    expect(result.current.value).toBe(3);
    expect(result.current.canRedo).toBe(false);
    act(() => result.current.undo());
    expect(result.current.value).toBe(1);
  5. const { result } = renderHook(() => useHistory('x'));
    act(() => result.current.undo());
    act(() => result.current.redo());
    expect(result.current.value).toBe('x');
  6. const { result } = renderHook(() => useHistory(0));
    act(() => {
      result.current.set(1);
      result.current.set(2);
    });
    act(() => result.current.undo());
    expect(result.current.value).toBe(1);