use-mutative
Version:
A hook to use Mutative as a React hook to efficient update react state immutable with mutable way
129 lines (99 loc) • 3.59 kB
Markdown

[](https://coveralls.io/github/mutativejs/use-mutative?branch=main)
[](https://www.npmjs.com/package/use-mutative)

A hook to use [Mutative](https://github.com/unadlib/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](https://mutative.js.org/docs/getting-started/performance).
Yarn
```bash
yarn add mutative use-mutative
```
NPM
```bash
npm install mutative use-mutative
```
Provide you can create immutable state easily with mutable way.
```tsx
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>
</>
);
}
```
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.
```tsx
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](https://github.com/mutativejs/use-mutative/blob/main/docs/modules.md)
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.
```tsx
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.
`use-mutative` is [MIT licensed](https://github.com/mutativejs/use-mutative/blob/main/LICENSE).