Skip to content

Commit e10f65d

Browse files
committed
Initial commit
0 parents  commit e10f65d

10 files changed

Lines changed: 1392 additions & 0 deletions

File tree

.editorconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# For more information about the properties used in
2+
# this file, please see the EditorConfig documentation:
3+
# http://editorconfig.org/
4+
5+
root = true
6+
7+
[*]
8+
charset = utf-8
9+
end_of_line = lf
10+
indent_size = 2
11+
indent_style = space
12+
insert_final_newline = true
13+
trim_trailing_whitespace = true
14+
15+
[*.md]
16+
trim_trailing_whitespace = false
17+
18+
[*.html]
19+
indent_size = 2
20+
21+
[{.travis.yml,package.json}]
22+
# The indent size used in the `package.json` file cannot be changed
23+
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
24+
indent_size = 2
25+
indent_style = space

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea
2+
node_modules
3+
dist
4+
docs

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2018 Mateusz Sienkan
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# React Immer Hooks
2+
3+
> Easy immutability in [React Hooks](https://reactjs.org/docs/hooks-intro.html) with [Immer](https://github.com/mweststrate/immer).
4+
5+
**Note:** _React Hooks are currently a [RFC proposal](https://github.com/reactjs/rfcs/pull/68) which may be subject to change. You'll need at least `react@16.7.0-alpha.0` to use this feature._
6+
7+
## Installation
8+
9+
`yarn add react-immer-hooks`
10+
11+
## Usage
12+
13+
##### useImmerState(initialState)
14+
15+
```jsx
16+
import { useImmerState } from 'react-immer-hooks'
17+
18+
const initialState = {
19+
clicks: 0,
20+
doubleClicks: 0
21+
}
22+
23+
const ClickCounters = () => {
24+
const [ state, setState ] = useImmerState(initialState)
25+
26+
const onClick = () => setState(draft => { draft.clicks++ })
27+
const onDoubleClick = () => setState(draft => { draft.doubleClicks++ })
28+
29+
return (
30+
<>
31+
<button onClick={onClick} onDoubleClick={onDoubleClick}>
32+
Clics: {state.clicks}, Double clicks: {state.doubleClicks}
33+
</button>
34+
</>
35+
)
36+
}
37+
```
38+
39+
##### useImmerReducer(reducer, initialState)
40+
41+
```jsx
42+
import { useImmerReducer } from 'react-immer-hooks'
43+
44+
const initialState = {
45+
count: 0
46+
}
47+
48+
const reducer = (draft, action) => {
49+
if (action.type === 'INCREMENT') draft.count++
50+
if (action.type === 'DECREMENT') draft.count--
51+
if (action.type === 'ADD') draft.count += action.payload
52+
}
53+
54+
const Counter = () => {
55+
const [ state, dispatch ] = useImmerReducer(reducer, initialState)
56+
57+
return (
58+
<>
59+
Count: {state.count}
60+
<button onClick={() => dispatch({ type: 'INCREMENT'})}>
61+
Increment
62+
</button>
63+
<button onClick={() => dispatch({ type: 'DECREMENT'})}>
64+
Decrement
65+
</button>
66+
<button onClick={() => dispatch({ type: 'ADD', payload: 5})}>
67+
Add 5
68+
</button>
69+
</>
70+
)
71+
}
72+
```
73+
74+
## License
75+
76+
MIT License

package.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "react-immer-hooks",
3+
"version": "0.1.0",
4+
"description": "Easy immutability in React Hooks.",
5+
"main": "dist/react-immer-hooks.js",
6+
"module": "dist/react-immer-hooks.mjs",
7+
"browser": "dist/react-immer-hooks.min.js",
8+
"source": "src/index.mjs",
9+
"repository": {
10+
"type": "git",
11+
"url": "https://github.com/sin/react-immer-hooks.git"
12+
},
13+
"author": "Mateusz Sienkan <sin.mateusz@gmail.com>",
14+
"license": "MIT",
15+
"scripts": {
16+
"build": "rollup -c",
17+
"dev": "rollup -c -w"
18+
},
19+
"devDependencies": {
20+
"@babel/core": "7",
21+
"@babel/preset-env": "^7.0.0",
22+
"rollup": "^0.65.2",
23+
"rollup-plugin-babel": "^4.0.3",
24+
"rollup-plugin-node-resolve": "^3.4.0"
25+
},
26+
"peerDependencies": {
27+
"react": "16.7.0-alpha.0",
28+
"immer": "^1.7.3"
29+
}
30+
}

rollup.config.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import resolve from 'rollup-plugin-node-resolve'
2+
import babel from 'rollup-plugin-babel'
3+
4+
const input = 'src/index.mjs'
5+
const output = 'dist/react-immer-hooks'
6+
7+
const sourcemap = true
8+
const external = []
9+
const plugins = [ resolve() ]
10+
const babelConfig = {
11+
babelrc: false,
12+
exclude: 'node_modules/**',
13+
presets: ['@babel/preset-env']
14+
}
15+
16+
export default [{
17+
input,
18+
output: {
19+
file: `${output}.mjs`,
20+
format: 'es',
21+
sourcemap
22+
},
23+
external,
24+
plugins
25+
},
26+
{
27+
input,
28+
output: {
29+
file: `${output}.js`,
30+
format: 'cjs',
31+
sourcemap
32+
},
33+
external,
34+
plugins
35+
},
36+
{
37+
input,
38+
output: {
39+
file: `${output}.min.js`,
40+
format: 'iife',
41+
name: 'ReactImmerHooks'
42+
},
43+
plugins: [
44+
...plugins,
45+
babel(babelConfig)
46+
]
47+
}]

src/index.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import useImmerState from './useImmerState'
2+
import useImmerReducer from './useImmerReducer'
3+
4+
export {
5+
useImmerState,
6+
useImmerReducer
7+
}

src/useImmerReducer.mjs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useReducer } from 'react'
2+
import produce from 'immer'
3+
4+
/**
5+
* Creates wrapped `useReducer`.
6+
*
7+
* @param {Any} initialState
8+
* @returns {[Any, Function]}
9+
*/
10+
11+
const useImmerReducer = (reducer, initialState) =>
12+
useReducer(produce(reducer), initialState)
13+
14+
export default useImmerReducer

src/useImmerState.mjs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { useState } from 'react'
2+
import produce from 'immer'
3+
4+
/**
5+
* Creates wrapped `useState`.
6+
*
7+
* @param {Any} initialState
8+
* @returns {[Any, Function]}
9+
*/
10+
11+
const useImmerState = initialState => {
12+
const [ state, setState ] = useState(initialState)
13+
14+
const setImmerState = setter => setState(produce(setter))
15+
16+
return [state, setImmerState]
17+
}
18+
19+
export default useImmerState

0 commit comments

Comments
 (0)