",
43 | "license": "MIT",
44 | "sideEffects": false,
45 | "dependencies": {
46 | "symbol-observable": "^1.2.0"
47 | },
48 | "devDependencies": {
49 | "@babel/cli": "^7.5.0",
50 | "@babel/core": "^7.5.4",
51 | "@babel/plugin-proposal-class-properties": "^7.5.0",
52 | "@babel/preset-env": "^7.5.4",
53 | "@babel/preset-react": "^7.0.0",
54 | "ava": "^2.2.0",
55 | "babel-eslint": "^10.0.2",
56 | "eslint": "^5.16.0",
57 | "eslint-config-mono": "^2.0.0",
58 | "eslint-config-standard-react": "^7.0.2",
59 | "eslint-plugin-import": "^2.18.0",
60 | "eslint-plugin-node": "^8.0.1",
61 | "eslint-plugin-promise": "^4.2.1",
62 | "eslint-plugin-react": "^7.14.2",
63 | "immer": "^3.1.3",
64 | "react": "^16.8.6",
65 | "rimraf": "^2.6.3"
66 | },
67 | "peerDependencies": {
68 | "react": "^16.7.* || ^16.8.*",
69 | "immer": "^1.8.* || ^2.* || ^3.*"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## react-immer
2 |
3 | [](https://travis-ci.org/monojack/react-immer)
4 | [](https://www.npmjs.com/package/react-immer)
5 | [](https://www.npmjs.com/package/react-immer)
6 | [](https://bundlephobia.com/result?p=react-immer@latest)
7 |
8 | No nonsense state management with [Immer](https://github.com/mweststrate/immer) and [React hooks](https://reactjs.org/docs/hooks-intro.html)
9 |
10 | **TL;DR**
11 |
12 | `index.js`
13 |
14 | ```js
15 | import React from 'react'
16 | import ReactDOM from 'react'
17 |
18 | import { createStore } from 'react-immer'
19 | import Counter from './Counter'
20 |
21 | createStore({ count: 1 })
22 |
23 | function App() {
24 | return
25 | }
26 |
27 | const rootElement = document.getElementById('root')
28 | ReactDOM.render( , rootElement)
29 | ```
30 |
31 |
32 |
33 | `Counter.js`
34 |
35 | ```js
36 | /* Counter.js */
37 |
38 | import React from 'react'
39 | import { useImmer } from 'react-immer'
40 |
41 | export default function Counter() {
42 | const [{ count }, produce] = useImmer({ count: state => state.count })
43 |
44 | const decrement = draft => {
45 | draft.count -= 1
46 | }
47 |
48 | const increment = draft => {
49 | draft.count += 1
50 | }
51 |
52 | return (
53 |
54 | produce(decrement)}>-
55 | {count}
56 | produce(increment)}>+
57 |
58 | )
59 | }
60 | ```
61 |
62 | [](https://codesandbox.io/s/yq328o9rvx)
63 |
64 | What's cool about **react-immer** is that if you don't support [Hooks](https://reactjs.org/docs/hooks-intro.html) yet, you can use it inline and it will work like a [render prop](https://reactjs.org/docs/render-props.html). In this case, it takes two arguments, the _spec object_ and the _render function_.
65 |
66 | ```js
67 | import { useImmer } from 'react-immer'
68 |
69 | // ...
70 | // useImmer(specObj, renderFn)
71 |
72 | {useImmer({ count: state => state.count }, ({ count }, produce) => (
73 |
74 | produce(decrement)}>-
75 | {count}
76 | produce(increment)}>+
77 |
78 | ))}
79 |
80 | ```
81 |
82 | Or, if you don't like the syntax, you can always use the **Immer** component
83 |
84 | ```js
85 | import { Immer } from 'react-immer'
86 | // ...
87 |
88 | state.count }}>
89 | {({ count }, produce) => (
90 |
91 | produce(decrement)}>-
92 | {count}
93 | produce(increment)}>+
94 |
95 | )}
96 |
97 | ```
98 |
--------------------------------------------------------------------------------