JAVASCRIPT

Implement Undo/Redo Functionality with useUndoRedo

A React hook that enables easy undo and redo capabilities for any piece of state, managing a history of changes for interactive applications like editors or drawing tools.

import { useState, useCallback } from 'react';

const useUndoRedo = (initialState) => {
  const [past, setPast] = useState([]);
  const [present, setPresent] = useState(initialState);
  const [future, setFuture] = useState([]);

  const set = useCallback((newState) => {
    if (newState === present) return; 

    setPast(prevPast => [...prevPast, present]);
    setPresent(newState);
    setFuture([]); 
  }, [present]);

  const undo = useCallback(() => {
    if (past.length === 0) return;

    const previous = past[past.length - 1];
    const newPast = past.slice(0, past.length - 1);

    setPast(newPast);
    setPresent(previous);
    setFuture(prevFuture => [present, ...prevFuture]);
  }, [past, present]);

  const redo = useCallback(() => {
    if (future.length === 0) return;

    const next = future[0];
    const newFuture = future.slice(1);

    setFuture(newFuture);
    setPast(prevPast => [...prevPast, present]);
    setPresent(next);
  }, [future, present]);

  const canUndo = past.length > 0;
  const canRedo = future.length > 0;

  return { present, set, undo, redo, canUndo, canRedo };
};

export default useUndoRedo;

/*
// Example Usage:
function DrawingApp() {
  const { present, set, undo, redo, canUndo, canRedo } = useUndoRedo('');

  return (
    <div>
      <input
        type="text"
        value={present}
        onChange={(e) => set(e.target.value)}
      />
      <button onClick={undo} disabled={!canUndo}>Undo</button>
      <button onClick={redo} disabled={!canRedo}>Redo</button>
      <p>Current: {present}</p>
    </div>
  );
}
*/
How it works: The `useUndoRedo` hook provides a flexible way to add undo and redo capabilities to any state in a React component. It manages three arrays: `past` (previous states), `present` (current state), and `future` (states that were undone and can be redone). The `set` function updates the `present` state and pushes the old `present` to `past`, clearing `future`. `undo` moves the `present` to `future` and restores the last `past` state, while `redo` reverses this operation. `canUndo` and `canRedo` booleans help manage button disabled states.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs