UNPKG

3.14 kBMarkdownView Raw
1# use-immer
2
3A hook to use [immer](https://github.com/mweststrate/immer) as a React [hook](https://reactjs.org/docs/hooks-intro.html) to manipulate state.
4
5# Installation
6
7`npm install immer use-immer`
8
9# API
10
11## useImmer
12
13`useImmer(initialState)` is very similar to [`useState`](https://reactjs.org/docs/hooks-state.html).
14The function returns a tuple, the first value of the tuple is the current state, the second is the updater function,
15which accepts an [immer producer function](https://immerjs.github.io/immer/produce) or a value as argument.
16
17### Managing state with immer producer function
18
19When passing a function to the updater, the `draft` argument can be mutated freely, until the producer ends and the changes will be made immutable and become the next state.
20
21Example: https://codesandbox.io/s/l97yrzw8ol
22
23```javascript
24import React from "react";
25import { useImmer } from "use-immer";
26
27
28function App() {
29 const [person, updatePerson] = useImmer({
30 name: "Michel",
31 age: 33
32 });
33
34 function updateName(name) {
35 updatePerson(draft => {
36 draft.name = name;
37 });
38 }
39
40 function becomeOlder() {
41 updatePerson(draft => {
42 draft.age++;
43 });
44 }
45
46 return (
47 <div className="App">
48 <h1>
49 Hello {person.name} ({person.age})
50 </h1>
51 <input
52 onChange={e => {
53 updateName(e.target.value);
54 }}
55 value={person.name}
56 />
57 <br />
58 <button onClick={becomeOlder}>Older</button>
59 </div>
60 );
61}
62```
63
64(obviously, immer is a little overkill for this example)
65
66### Managing state as simple useState hook
67When passing a value to the updater instead of a function, `useImmer` hook behaves the same as useState hook and updates the state with that value.
68
69```javascript
70import React from 'react';
71import { useImmer } from 'use-immer';
72
73function BirthDayCelebrator(){
74 const [age, setAge] = useImmer(20);
75
76 function birthDay(event){
77 setAge(age + 1);
78 alert(`Happy birthday #${age} Anon! hope you good`);
79 }
80
81 return(
82 <div>
83 <button onClick={birthDay}>It is my birthday</button>
84 </div>
85 );
86}
87```
88
89Obviously if you have to deal with immutability it is better option passing a function to the updater instead of a direct value.
90
91## useImmerReducer
92
93Immer powered reducer, based on [`useReducer` hook](https://reactjs.org/docs/hooks-reference.html#usereducer)
94
95Example: https://codesandbox.io/s/2zor1monvp
96
97```javascript
98import React from "react";
99import { useImmerReducer } from "use-immer";
100
101const initialState = { count: 0 };
102
103function reducer(draft, action) {
104 switch (action.type) {
105 case "reset":
106 return initialState;
107 case "increment":
108 return void draft.count++;
109 case "decrement":
110 return void draft.count--;
111 }
112}
113
114function Counter() {
115 const [state, dispatch] = useImmerReducer(reducer, initialState);
116 return (
117 <>
118 Count: {state.count}
119 <button onClick={() => dispatch({ type: "reset" })}>Reset</button>
120 <button onClick={() => dispatch({ type: "increment" })}>+</button>
121 <button onClick={() => dispatch({ type: "decrement" })}>-</button>
122 </>
123 );
124}
125```