Build a counter with undo and redo. The trick isn't the counting — it's remembering history: keep every value the counter has been in an array, plus a pointer (index) to the current one. Undo moves the pointer back, redo moves it forward, and a new change after an undo discards the redo "future."
// A self-contained component. No props.
function App(): JSX.Element;
A count, +1 / -1 buttons, and Undo / Redo.
+1, +1, +1 → history [0,1,2,3], index 3, count 3
undo, undo → index 1, count 1 (history unchanged)
redo → index 2, count 2
after undo to index 1, press +1 → the redo future is dropped:
history becomes [0,1,2], index 2, count 2
history is every value seen; index points at the current; count = history[index].index, then appends — no orphaned redo branch.index within bounds.index 0; redo off at the last index.