Skip to content

mutativejs/use-mutative

Folders and files

NameName
Last commit message
Last commit date

Latest commit

1c1d6c7 · May 22, 2025
May 10, 2025
Jun 13, 2024
May 22, 2025
Jun 13, 2024
Feb 29, 2024
Feb 29, 2024
Feb 29, 2024
Feb 29, 2024
Feb 29, 2024
Feb 29, 2024
Jan 2, 2023
Jun 13, 2024
Feb 29, 2024
May 22, 2025
May 19, 2024
Feb 29, 2024
May 22, 2025

Repository files navigation

use-mutative

Node CI Coverage Status npm license

A hook to use Mutative as a React hook to efficient update react state immutable with mutable way.

use-mutative is 2-6x faster than useState() with spread operation, more than 10x faster than useImmer(). Read more about the performance comparison in Mutative.

Installation

Yarn

yarn add mutative use-mutative

NPM

npm install mutative use-mutative

API

useMutative()

Provide you can create immutable state easily with mutable way.

import { useMutative } from 'use-mutative';

export function App() {
  const [todos, setTodos] = useMutative([{ text: 'todo' }]);
  return (
    <>
      <button
        onClick={() => {
          // set todos with draft mutable
          setTodos((draft) => {
            draft.push({ text: 'todo 2' });
          });
        }}
      >
        click
      </button>
      <button
        onClick={() => {
          // also can override value directly
          setTodos([{ text: 'todo' }, { text: 'todo 2' }]);
        }}
      >
        click
      </button>
    </>
  );
}

useMutativeReducer()

Provide you can create immutable state easily with mutable way in reducer way.

For return values that do not contain any drafts, you can use rawReturn() to wrap this return value to improve performance. It ensure that the return value is only returned explicitly.

import { rawReturn } from 'mutative';
import { useMutativeReducer } from 'use-mutative';

const initialState = {
  count: 0,
};

function reducer(
  draft: Draft<typeof initialState>,
  action: { type: 'reset' | 'increment' | 'decrement' }
) {
  switch (action.type) {
    case 'reset':
      return rawReturn(initialState);
    case 'increment':
      return void draft.count++;
    case 'decrement':
      return void draft.count--;
  }
}

export function App() {
  const [state, dispatch] = useMutativeReducer(reducer, initialState);

  return (
    <div>
      Count: {state.count}
      <br />
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

More detail about use-mutative can be found in API docs

Patches

In some cases, you may want to get that patches from your update, we can pass { enablePatches: true } options in useMutative() or useMutativeReducer(), that can provide you the ability to get that patches from pervious action.

const [state, updateState, patches, inversePatches] = useMutative(initState, {
  enablePatches: true,
});

const [state, dispatch, patches, inversePatches] = useMutativeReducer(
  reducer,
  initState,
  initializer,
  { enablePatches: true }
);

patches format will follow https://jsonpatch.com/, but the "path" field be array structure.

License

use-mutative is MIT licensed.

About

A 2-6x faster alternative to useState with spread operation.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published