useClonedState

Tags:

A React Hook for creating a cloned state that supports modification, synchronous operation, and isolation from each other, with support for custom clone functions, defaulting to JSON.parse(JSON.stringify(source)).

Scenes

  • Data state cloning and isolation scenario: Implements deep cloning of data to create separate states for editing without affecting the original data
  • Edit history tracking scenario: Maintains a history of data edits to support undo and redo functions
  • Data comparison scenario: Offers functionality to compare original and modified data
  • ...

Demo

Source
State:
{ "name": "shined", "age": 18 }
Cloned state:
{ "name": "shined", "age": 18 }
name:

Usage

const [form, setForm] = useSafeState({
  name: 'react-use',
  description: 'An awesome react hooks library.',
})

const [cloned, setCloned, syncSource] = useClonedState(form)

// Modify the clone state directly, i.e., "edit the form", data is isolated from the source state
const handleModify = (e: React.ChangeEvent<HTMLInputElement>) => {
  setCloned((cloned) => ({
    ...cloned,
    [e.target.name]: e.target.value,
  }))
}

// Use the current state of the clone as the new form state, i.e., "save changes"
const handleSave = () => setForm(cloned)

// Synchronize (reset) the source state with the clone state, i.e., "undo changes"
const handleReset = () => syncSource()

Source

Click links below to view source on GitHub.

API

const [cloned, setCloned, syncSource] = useClonedState(source, options)

Source

Any valid JavaScript data type, such as string, number, object, array, etc.

Options

export type UseClonedStateOptions = {
  /**
   * Clone function
   *
   * @defaultValue defaultCloneFn (Implemented simply using JSON.parse(JSON.stringify(source)))
   */
  clone?: <T>(source: T) => T
  /**
   * Whether to manually trigger the synchronize (syncSource) function when the input state changes, defaulting to manual.
   *
   * @defaultValue true
   */
  manual?: boolean
  /**
   * Whether to perform a deep comparison of the input state and trigger the synchronize (syncSource) function only if the deep comparison result is false.
   * 
   * deep comparison is enabled by default
   *
   * @defaultValue true
   */
  deep?: boolean
}

Returns

export type UseClonedStateReturns<T> = readonly [
  /**
   * Cloned state
   */
  cloned: T,
  /**
   * Set cloned state
   */
  setCloned: ReactSetState<T>,
  /**
   * Synchronize cloned state with source state
   */
  syncSource: () => void,
]