Docs
HistoryState

HistoryState

Add undo / redo functionality

About

The useHistoryState hook is beneficial for managing state with undo and redo capabilities in React components. It offers functions like undo, redo, set, and clear to interact with the state, along with values like canUndo and canRedo to reflect the state’s status.

Parameters

NameTypeDescription
initialPresentobject(Optional) The initial state value. Default: {}.

Return Values

NameTypeDescription
stateanyThe current state value.
setfunctionA function to set the state value.
undofunctionA function to undo the previous state.
redofunctionA function to redo the next state.
clearfunctionA function to clear the state history and reset the state.
canUndobooleanIndicates whether an undo action is available.
canRedobooleanIndicates whether a redo action is available.

Installation

Run the following command:

npx scriptkavi-hooks@latest add history-state

Usage

import { useHistoryState } from "@/hooks/history-state"
import * as React from "react"
 
import Form from "./Form"
 
export default function App() {
  const { state, set, undo, redo, clear, canUndo, canRedo } = useHistoryState({
    items: [],
  })
 
  const addTodo = (val) => {
    set({
      ...state,
      items: state.items.concat({ id: crypto.randomUUID(), name: val }),
    })
  }
 
  const removeTodo = (id) => {
    set({
      ...state,
      items: state.items.filter((item) => item.id !== id),
    })
  }
 
  return (
    <section>
      <header>
        <h1>useHistoryState</h1>
        <div>
          <button disabled={!canUndo} className="link" onClick={undo}>
            Undo
          </button>
          <button disabled={!canRedo} className="link" onClick={redo}>
            Redo
          </button>
 
          <button
            disabled={!state.items.length}
            className="link"
            onClick={clear}
          >
            Clear
          </button>
        </div>
        <Form addItem={addTodo} />
      </header>
 
      <ul>
        {state.items.map((item, index) => {
          return (
            <li key={index}>
              <span>{item.name}</span>
              <button className="link" onClick={() => removeTodo(item.id)}>
                Delete
              </button>
            </li>
          )
        })}
      </ul>
    </section>
  )
}