reactish-state 0.11.0-alpha.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -16
- package/dist/cjs/index.js +1 -1
- package/dist/esm/vanilla/selector.js +1 -1
- package/dist/middleware/cjs/index.js +3 -2
- package/dist/middleware/esm/applyMiddleware.js +3 -2
- package/package.json +25 -25
package/README.md
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
# Reactish-State
|
|
2
2
|
|
|
3
|
-
> Simple, decentralized state management for React.
|
|
3
|
+
> Simple, decentralized(atomic) state management for React.
|
|
4
|
+
|
|
5
|
+
## ✨Highlights✨
|
|
6
|
+
|
|
7
|
+
- Decentralized state management
|
|
8
|
+
- Un-opinionated and easy-to-use API
|
|
9
|
+
- No need of wrapping app in Context or prop drilling
|
|
10
|
+
- React components re-render only on changes
|
|
11
|
+
- Compatible with React 18 concurrent rendering
|
|
12
|
+
- Selectors are memoized by default
|
|
13
|
+
- Feature extensible with middleware or plugins
|
|
14
|
+
- States persistable to browser storage
|
|
15
|
+
- Support Redux dev tools via middleware
|
|
16
|
+
- [~1KB](https://bundlephobia.com/package/reactish-state): simple and small
|
|
4
17
|
|
|
5
18
|
## Install
|
|
6
19
|
|
|
@@ -94,9 +107,9 @@ The state management solutions in the React ecosystem have popularized two state
|
|
|
94
107
|
|
|
95
108
|
- **Centralized**: a single store that combines entire app states together and slices of the store are connected to React components through selectors. Examples: react-redux, Zustand.
|
|
96
109
|
|
|
97
|
-
- **Decentralized**: consisting of many small states which can build up state dependency trees using a bottom-up approach. React components only need to connect with the states that they use. Examples: Recoil, Jotai.
|
|
110
|
+
- **Decentralized**: consisting of many small(atomic) states which can build up state dependency trees using a bottom-up approach. React components only need to connect with the states that they use. Examples: Recoil, Jotai.
|
|
98
111
|
|
|
99
|
-
This library adopts the decentralized state model, offering a _Recoil-like_ API, but with a much simpler and smaller implementation(similar to Zustand), which makes it the one of the smallest state management solutions with gzipped bundle size
|
|
112
|
+
This library adopts the decentralized state model, offering a _Recoil-like_ API, but with a much simpler and smaller implementation(similar to Zustand), which makes it the one of the smallest state management solutions with gzipped bundle size around 1KB.
|
|
100
113
|
|
|
101
114
|
| | State model | Bundle size |
|
|
102
115
|
| --- | --- | --- |
|
|
@@ -142,19 +155,6 @@ The difference might sound insignificant, but imaging every single state update
|
|
|
142
155
|
- No need to use a React Hook to extract actions from the store.
|
|
143
156
|
- Actions come from outside React and no need to add them into the `useCallback/useEffect` dep array.
|
|
144
157
|
|
|
145
|
-
## ✨Highlights✨
|
|
146
|
-
|
|
147
|
-
- Decentralized state management
|
|
148
|
-
- Un-opinionated and easy-to-use API
|
|
149
|
-
- No need of wrapping app in Context or prop drilling
|
|
150
|
-
- React components re-render only on changes
|
|
151
|
-
- Compatible with React 18 concurrent rendering
|
|
152
|
-
- Selectors are memoized by default
|
|
153
|
-
- Feature extensible with middleware or plugins
|
|
154
|
-
- States persistable to browser storage
|
|
155
|
-
- Support Redux dev tools via middleware
|
|
156
|
-
- Less than 1KB: simple and small
|
|
157
|
-
|
|
158
158
|
# Recipes
|
|
159
159
|
|
|
160
160
|
## States should be updated immutably
|
|
@@ -303,6 +303,55 @@ const Example = () => {
|
|
|
303
303
|
};
|
|
304
304
|
```
|
|
305
305
|
|
|
306
|
+
## Selector that depends on props or local states
|
|
307
|
+
|
|
308
|
+
The `selector` function allows us to create reusable derived states outside React components. In contrast, component-scoped derived states which depend on props or local states can be created by the `useSelector` hook.
|
|
309
|
+
|
|
310
|
+
```jsx
|
|
311
|
+
import { state, useSelector } from "reactish-state";
|
|
312
|
+
|
|
313
|
+
const todosState = state([{ task: "Shop groceries", completed: false }]);
|
|
314
|
+
|
|
315
|
+
const FilteredTodoList = ({ filter = "ALL" }) => {
|
|
316
|
+
const filteredTodos = useSelector(
|
|
317
|
+
() => [
|
|
318
|
+
todosState,
|
|
319
|
+
(todos) => {
|
|
320
|
+
switch (filter) {
|
|
321
|
+
case "ALL":
|
|
322
|
+
return todos;
|
|
323
|
+
case "COMPLETED":
|
|
324
|
+
return todos.filter((todo) => todo.completed);
|
|
325
|
+
case "ACTIVE":
|
|
326
|
+
return todos.filter((todo) => !todo.completed);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
],
|
|
330
|
+
[filter]
|
|
331
|
+
);
|
|
332
|
+
// Render filtered todos...
|
|
333
|
+
};
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The second parameter of `useSelector` is a dependency array (similar to React's `useMemo` hook), in which you can specify what props or local states the selector depends on. In the above example, `FilteredTodoList` component will re-render only if the global `todosState` state or local `filter` prop have been updated.
|
|
337
|
+
|
|
338
|
+
### Linting the dependency array of useSelector
|
|
339
|
+
|
|
340
|
+
You can take advantage of the [eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks) package to lint the dependency array of `useSelector`. Add the following configuration into your ESLint config file:
|
|
341
|
+
|
|
342
|
+
```json
|
|
343
|
+
{
|
|
344
|
+
"rules": {
|
|
345
|
+
"react-hooks/exhaustive-deps": [
|
|
346
|
+
"warn",
|
|
347
|
+
{
|
|
348
|
+
"additionalHooks": "useSelector"
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
306
355
|
## Still perfer Redux-like reducers?
|
|
307
356
|
|
|
308
357
|
```js
|
package/dist/cjs/index.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
const applyMiddleware = (middlewares, {
|
|
4
4
|
fromRight
|
|
5
|
-
} = {}) => (api, config) => middlewares[fromRight ? 'reduceRight' : 'reduce']((set, middleware) => middleware ? middleware(
|
|
5
|
+
} = {}) => (api, config) => middlewares[fromRight ? 'reduceRight' : 'reduce']((set, middleware) => middleware ? middleware({
|
|
6
|
+
...api,
|
|
6
7
|
set
|
|
7
|
-
}
|
|
8
|
+
}, config) : set, api.set);
|
|
8
9
|
|
|
9
10
|
const persist = ({
|
|
10
11
|
prefix,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const applyMiddleware = (middlewares, {
|
|
2
2
|
fromRight
|
|
3
|
-
} = {}) => (api, config) => middlewares[fromRight ? 'reduceRight' : 'reduce']((set, middleware) => middleware ? middleware(
|
|
3
|
+
} = {}) => (api, config) => middlewares[fromRight ? 'reduceRight' : 'reduce']((set, middleware) => middleware ? middleware({
|
|
4
|
+
...api,
|
|
4
5
|
set
|
|
5
|
-
}
|
|
6
|
+
}, config) : set, api.set);
|
|
6
7
|
|
|
7
8
|
export { applyMiddleware };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactish-state",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Simple, decentralized state management for React.",
|
|
5
5
|
"author": "Zheng Song",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"bundle": "rollup -c",
|
|
28
28
|
"watch": "rollup -c -w",
|
|
29
29
|
"clean": "rm -Rf dist types",
|
|
30
|
-
"post-build": "rm -Rf types/__tests__",
|
|
31
30
|
"types": "tsc",
|
|
31
|
+
"posttypes": "rm -Rf types/__tests__",
|
|
32
32
|
"lint": "eslint .",
|
|
33
33
|
"lint:fix": "eslint --fix .",
|
|
34
34
|
"pret": "prettier -c .",
|
|
35
35
|
"pret:fix": "prettier -w .",
|
|
36
|
-
"build": "run-s pret clean lint types bundle
|
|
36
|
+
"build": "run-s pret clean lint types bundle",
|
|
37
37
|
"test": "jest",
|
|
38
38
|
"test:watch": "jest --watch",
|
|
39
39
|
"eg": "npm run dev --prefix examples"
|
|
@@ -73,35 +73,35 @@
|
|
|
73
73
|
"use-sync-external-store": "^1.2.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@babel/core": "^7.
|
|
77
|
-
"@babel/preset-env": "^7.
|
|
78
|
-
"@babel/preset-react": "^7.
|
|
79
|
-
"@babel/preset-typescript": "^7.
|
|
76
|
+
"@babel/core": "^7.23.2",
|
|
77
|
+
"@babel/preset-env": "^7.23.2",
|
|
78
|
+
"@babel/preset-react": "^7.22.15",
|
|
79
|
+
"@babel/preset-typescript": "^7.23.2",
|
|
80
80
|
"@redux-devtools/extension": "^3.2.5",
|
|
81
|
-
"@rollup/plugin-babel": "^6.0.
|
|
82
|
-
"@rollup/plugin-node-resolve": "^15.
|
|
83
|
-
"@testing-library/jest-dom": "^
|
|
81
|
+
"@rollup/plugin-babel": "^6.0.4",
|
|
82
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
83
|
+
"@testing-library/jest-dom": "^6.1.4",
|
|
84
84
|
"@testing-library/react": "^14.0.0",
|
|
85
|
-
"@types/jest": "^29.5.
|
|
86
|
-
"@types/react": "^18.
|
|
87
|
-
"@types/use-sync-external-store": "^0.0.
|
|
88
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
89
|
-
"@typescript-eslint/parser": "^
|
|
85
|
+
"@types/jest": "^29.5.7",
|
|
86
|
+
"@types/react": "^18.2.34",
|
|
87
|
+
"@types/use-sync-external-store": "^0.0.5",
|
|
88
|
+
"@typescript-eslint/eslint-plugin": "^6.9.1",
|
|
89
|
+
"@typescript-eslint/parser": "^6.9.1",
|
|
90
90
|
"babel-plugin-pure-annotations": "^0.1.2",
|
|
91
|
-
"eslint": "^8.
|
|
92
|
-
"eslint-config-prettier": "^
|
|
93
|
-
"eslint-plugin-jest": "^27.
|
|
94
|
-
"eslint-plugin-react": "^7.
|
|
91
|
+
"eslint": "^8.53.0",
|
|
92
|
+
"eslint-config-prettier": "^9.0.0",
|
|
93
|
+
"eslint-plugin-jest": "^27.6.0",
|
|
94
|
+
"eslint-plugin-react": "^7.33.2",
|
|
95
95
|
"eslint-plugin-react-hooks": "^4.6.0",
|
|
96
96
|
"eslint-plugin-react-hooks-addons": "^0.3.1",
|
|
97
|
-
"immer": "^
|
|
98
|
-
"jest": "^29.
|
|
99
|
-
"jest-environment-jsdom": "^29.
|
|
97
|
+
"immer": "^10.0.3",
|
|
98
|
+
"jest": "^29.7.0",
|
|
99
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
100
100
|
"npm-run-all": "^4.1.5",
|
|
101
|
-
"prettier": "^
|
|
101
|
+
"prettier": "^3.0.3",
|
|
102
102
|
"react": "^18.2.0",
|
|
103
103
|
"react-dom": "^18.2.0",
|
|
104
|
-
"rollup": "^3.
|
|
105
|
-
"typescript": "^5.
|
|
104
|
+
"rollup": "^4.3.0",
|
|
105
|
+
"typescript": "^5.2.2"
|
|
106
106
|
}
|
|
107
107
|
}
|