https://github.com/mutativejs/use-mutative
A 2-6x faster alternative to useState with spread operation.
https://github.com/mutativejs/use-mutative
immutability immutable mutative react react-hooks
Last synced: 9 months ago
JSON representation
A 2-6x faster alternative to useState with spread operation.
- Host: GitHub
- URL: https://github.com/mutativejs/use-mutative
- Owner: mutativejs
- License: mit
- Created: 2022-10-29T09:24:38.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-02-16T02:10:31.000Z (11 months ago)
- Last Synced: 2025-03-28T15:05:13.423Z (9 months ago)
- Topics: immutability, immutable, mutative, react, react-hooks
- Language: TypeScript
- Homepage:
- Size: 1.08 MB
- Stars: 70
- Watchers: 4
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# use-mutative

[](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).
## Installation
Yarn
```bash
yarn add mutative use-mutative
```
NPM
```bash
npm install mutative use-mutative
```
## API
### useMutative()
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 (
<>
{
// set todos with draft mutable
setTodos((draft) => {
draft.push({ text: 'todo 2' });
});
}}
>
click
{
// also can override value directly
setTodos([{ text: 'todo' }, { text: 'todo 2' }]);
}}
>
click
>
);
}
```
### 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.
```tsx
import { rawReturn } from 'mutative';
import { useMutativeReducer } from 'use-mutative';
const initialState = {
count: 0,
};
function reducer(
draft: Draft,
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 (
Count: {state.count}
dispatch({ type: 'increment' })}>Increment
dispatch({ type: 'decrement' })}>Decrement
dispatch({ type: 'reset' })}>Reset
);
}
```
More detail about `use-mutative` can be found in [API docs](https://github.com/mutativejs/use-mutative/blob/main/docs/modules.md)
### 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.
```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.
## License
`use-mutative` is [MIT licensed](https://github.com/mutativejs/use-mutative/blob/main/LICENSE).