redux-astroglide 0.1.0 → 0.1.3
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 +125 -60
- package/dist/index.es.js +1 -3916
- package/dist/index.js +1 -3925
- package/dist/index.umd.js +1 -5983
- package/dist/plugins/index.es.js +1 -318
- package/dist/plugins/index.js +1 -331
- package/dist/plugins/index.umd.js +1 -415
- package/dist/plugins/persist/index.es.js +1 -64
- package/dist/plugins/persist/index.js +1 -71
- package/dist/plugins/persist/index.umd.js +1 -77
- package/dist/plugins/set/index.es.js +1 -17
- package/dist/plugins/set/index.js +1 -19
- package/dist/plugins/set/index.umd.js +1 -25
- package/dist/plugins/type/index.es.js +1 -104
- package/dist/plugins/type/index.js +1 -110
- package/dist/plugins/type/index.umd.js +1 -194
- package/package.json +5 -6
package/README.md
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# Redux-Astroglide
|
|
2
2
|
|
|
3
|
-
####
|
|
4
|
-
|
|
3
|
+
#### Taking the pain out of state management by squeezing a huge package into a tiny API
|
|
4
|
+
|
|
5
|
+
Astroglide is a set of configuration and automation tools built on top of Redux Toolkit in order to provide the most succinct API with the least boilerplate possible. It's the easiest way to get up and running with redux state, and has the lowest mental overhead of any state management tool for React.
|
|
6
|
+
|
|
7
|
+
We stay DRY so you don't have to.
|
|
5
8
|
|
|
6
9
|
## Installation
|
|
7
10
|
|
|
@@ -15,13 +18,13 @@ npm install redux-astroglide
|
|
|
15
18
|
|
|
16
19
|
# Yarn
|
|
17
20
|
yarn add redux-astroglide
|
|
18
|
-
|
|
21
|
+
|
|
19
22
|
# PNPM
|
|
20
23
|
pnpm add redux-astroglide
|
|
21
24
|
|
|
22
25
|
```
|
|
23
|
-
|
|
24
26
|
|
|
27
|
+
|
|
25
28
|
|
|
26
29
|
## Setup
|
|
27
30
|
|
|
@@ -34,12 +37,11 @@ import configure from "redux-astroglide";
|
|
|
34
37
|
const { store, createSlice } = configure({
|
|
35
38
|
// ... (configureStore options
|
|
36
39
|
});
|
|
37
|
-
|
|
38
40
|
```
|
|
39
|
-
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
|
|
44
|
+
[Learn more about RTK's configureStore function](https://redux-toolkit.js.org/usage/usage-with-typescript#configurestore)
|
|
43
45
|
|
|
44
46
|
Now just create a slice anywhere in your application and in addition to the actions created by Redux Toolkit you'll get some memoized selectors and hooks from Astroglide:
|
|
45
47
|
|
|
@@ -48,7 +50,8 @@ import { createSlice } from "../../app/store";
|
|
|
48
50
|
|
|
49
51
|
const slice = createSlice(
|
|
50
52
|
"LoginForm", // reducer namespace
|
|
51
|
-
{
|
|
53
|
+
{
|
|
54
|
+
// initial state
|
|
52
55
|
username: "",
|
|
53
56
|
password: "",
|
|
54
57
|
}
|
|
@@ -58,8 +61,8 @@ export const { setPassword, setUsername } = slice.actions;
|
|
|
58
61
|
export const { selectUsername, selectPassword } = slice.selectors;
|
|
59
62
|
export const { useUsername, usePassword } = slice.hooks;
|
|
60
63
|
```
|
|
61
|
-
|
|
62
64
|
|
|
65
|
+
|
|
63
66
|
|
|
64
67
|
You can also create the slice using [the same API specified by RTK](https://redux-toolkit.js.org/usage/usage-with-typescript#createslice).
|
|
65
68
|
|
|
@@ -74,10 +77,10 @@ const slice = createSlice({
|
|
|
74
77
|
// custom reducers are the most likely reason to use this syntax
|
|
75
78
|
},
|
|
76
79
|
// other RTK functionality can go here
|
|
77
|
-
})
|
|
80
|
+
});
|
|
78
81
|
```
|
|
79
|
-
|
|
80
82
|
|
|
83
|
+
|
|
81
84
|
|
|
82
85
|
## Usage
|
|
83
86
|
|
|
@@ -87,15 +90,33 @@ These hooks can be used in a React component with the same API as React's setSta
|
|
|
87
90
|
export const UsernameField = (props) => {
|
|
88
91
|
const [username, setUsername] = useUsername();
|
|
89
92
|
|
|
90
|
-
return
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
return (
|
|
94
|
+
<input
|
|
95
|
+
name="username"
|
|
96
|
+
type="text"
|
|
97
|
+
value={username}
|
|
98
|
+
onChange={(e) => setUsername(e.target.value)} // this triggers a redux action
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
97
102
|
```
|
|
98
|
-
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
The setter actions can be passed a function to receive a copy of the latest state value, just like with React's setState:
|
|
107
|
+
|
|
108
|
+
```jsx
|
|
109
|
+
<input
|
|
110
|
+
//...
|
|
111
|
+
onChange={(e) =>
|
|
112
|
+
setUsername((currentUsername) =>
|
|
113
|
+
isValid(e.target.value) ? e.target.value : currentUsername
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
/>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
|
|
99
120
|
|
|
100
121
|
Astroglide's createSlice exposes global domain selectors and setters, if you need something like that:
|
|
101
122
|
|
|
@@ -108,51 +129,71 @@ export { useSlice } = slice.hooks;
|
|
|
108
129
|
export { selectSlice } = slice.selectors;
|
|
109
130
|
export { setSlice } = slice.actions; // will not conflict with existing `slice` prop actions
|
|
110
131
|
```
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
The setter actions can be passed a function to receive a copy of the latest state value, just like with React's setState:
|
|
115
|
-
|
|
116
|
-
```jsx
|
|
117
|
-
<input
|
|
118
|
-
//...
|
|
119
|
-
onChange={e => setUsername(currentUsername =>
|
|
120
|
-
isValid(e.target.value) ? e.target.value : currentUsername
|
|
121
|
-
)}
|
|
122
|
-
/>
|
|
123
|
-
```
|
|
124
|
-
|
|
125
132
|
|
|
133
|
+
|
|
126
134
|
|
|
127
135
|
The hooks can also be used outside of a React component (like in a thunk or saga) by destructuring the `select` and `update` props. This allows your reducer file to export as few variables as possible:
|
|
128
136
|
|
|
129
137
|
```jsx
|
|
130
138
|
// thunk.js
|
|
131
139
|
import { createAsyncThunk } from "@reduxjs/toolkit";
|
|
132
|
-
import { useUsername, usePassword } from "./slice";
|
|
133
140
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
141
|
+
import { useUsername, usePassword } from "./slice";
|
|
142
|
+
// OR
|
|
143
|
+
import {
|
|
144
|
+
selectUsername,
|
|
145
|
+
setUsername,
|
|
146
|
+
selectPassword,
|
|
147
|
+
setPassword,
|
|
148
|
+
} from "./slice";
|
|
149
|
+
|
|
150
|
+
const loginThunk = createAsyncThunk(
|
|
151
|
+
"login",
|
|
152
|
+
async (args, { dispatch, getState }) => {
|
|
138
153
|
const username = useUsername.select(getState());
|
|
139
154
|
const password = usePassword.select(getState());
|
|
140
155
|
// logic ...
|
|
141
|
-
|
|
156
|
+
dispatch(useUsername.update("newUsername"));
|
|
142
157
|
// ...
|
|
143
158
|
|
|
144
159
|
// OR
|
|
145
160
|
|
|
146
|
-
const username = selectUsername(getState)
|
|
147
|
-
const password = selectPassword(getState)
|
|
161
|
+
const username = selectUsername(getState());
|
|
162
|
+
const password = selectPassword(getState());
|
|
148
163
|
// logic ...
|
|
149
|
-
|
|
164
|
+
dispatch(setUsername("newUsername"));
|
|
150
165
|
// ...
|
|
151
|
-
|
|
152
166
|
}
|
|
153
|
-
)
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
// saga.js
|
|
170
|
+
import { select, put } from "redux-saga/effects";
|
|
171
|
+
|
|
172
|
+
import { useUsername, usePassword } from "./slice";
|
|
173
|
+
// OR
|
|
174
|
+
import {
|
|
175
|
+
selectUsername,
|
|
176
|
+
setUsername,
|
|
177
|
+
selectPassword,
|
|
178
|
+
setPassword,
|
|
179
|
+
} from "./slice";
|
|
180
|
+
|
|
181
|
+
function* loginSaga(action) {
|
|
182
|
+
const username = yield select(useUsername.select);
|
|
183
|
+
const password = yield select(usePassword.select);
|
|
184
|
+
// logic ...
|
|
185
|
+
yield put(useUsername.update("newUsername"));
|
|
186
|
+
|
|
187
|
+
// OR
|
|
188
|
+
|
|
189
|
+
const username = yield select(selectUsername);
|
|
190
|
+
const password = yield select(selectPassword);
|
|
191
|
+
// logic ...
|
|
192
|
+
yield put(setUsername("newUsername"));
|
|
193
|
+
}
|
|
154
194
|
```
|
|
155
|
-
|
|
195
|
+
|
|
196
|
+
|
|
156
197
|
|
|
157
198
|
Astroglide also provides some of its internal helper functions you may find useful:
|
|
158
199
|
|
|
@@ -164,10 +205,11 @@ export const {
|
|
|
164
205
|
createSlice,
|
|
165
206
|
injectReducer,
|
|
166
207
|
injectSlice,
|
|
167
|
-
injectMiddleware
|
|
208
|
+
injectMiddleware,
|
|
168
209
|
} = configure();
|
|
169
210
|
```
|
|
170
|
-
|
|
211
|
+
|
|
212
|
+
|
|
171
213
|
|
|
172
214
|
## Plugins
|
|
173
215
|
|
|
@@ -177,21 +219,21 @@ Astroglide ships with a handful of plugins you can use for things like typecheck
|
|
|
177
219
|
// Login/slice.js
|
|
178
220
|
const slice = createSlice("Login", {
|
|
179
221
|
username: type(PropType.string, ""),
|
|
180
|
-
password: type(PropTypes.string, "", { shouldPreventUpdate: true })
|
|
222
|
+
password: type(PropTypes.string, "", { shouldPreventUpdate: true }),
|
|
181
223
|
});
|
|
182
224
|
|
|
183
225
|
// Nav/slice.js
|
|
184
226
|
const slice = createSlice("Nav", {
|
|
185
|
-
isOpen:
|
|
186
|
-
storageType: localStorage
|
|
187
|
-
})
|
|
188
|
-
clickCount:
|
|
227
|
+
isOpen: persist("", {
|
|
228
|
+
storageType: localStorage,
|
|
229
|
+
}),
|
|
230
|
+
clickCount: set((value) => value + 1),
|
|
189
231
|
});
|
|
190
232
|
```
|
|
191
|
-
|
|
192
233
|
|
|
193
|
-
|
|
234
|
+
|
|
194
235
|
|
|
236
|
+
These plugins are loaded by adding this to your Astroglide configuration:
|
|
195
237
|
|
|
196
238
|
```jsx
|
|
197
239
|
import configure, { addPlugins } from "redux-astroglide";
|
|
@@ -210,8 +252,30 @@ export const [set, type, persist] = addPlugins(
|
|
|
210
252
|
|
|
211
253
|
export const { store, createSlice } = configure();
|
|
212
254
|
```
|
|
213
|
-
|
|
214
255
|
|
|
256
|
+
Plugins like persist also export their own tools:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
import {
|
|
260
|
+
getPersistedValue,
|
|
261
|
+
storePersistedValue,
|
|
262
|
+
} from "redux-astroglide/plugins/persist";
|
|
263
|
+
|
|
264
|
+
const currentValue = getPersistedValue(
|
|
265
|
+
"isOpen",
|
|
266
|
+
"Nav"
|
|
267
|
+
// storageType: localStorage | sessionStorage | { getItem, setItem }
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
storePersistedValue(
|
|
271
|
+
"isOpen",
|
|
272
|
+
"Nav",
|
|
273
|
+
true
|
|
274
|
+
// storageType: localStorage | sessionStorage { getItem, setItem }
|
|
275
|
+
);
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
|
|
215
279
|
|
|
216
280
|
## Custom Plugins
|
|
217
281
|
|
|
@@ -234,22 +298,23 @@ addPlugin({
|
|
|
234
298
|
return value;
|
|
235
299
|
},
|
|
236
300
|
})
|
|
237
|
-
// or
|
|
301
|
+
// or
|
|
238
302
|
addPlugins({
|
|
239
303
|
// plugin 1
|
|
240
304
|
}, {
|
|
241
305
|
// plugin 2
|
|
242
306
|
})
|
|
243
|
-
|
|
307
|
+
|
|
244
308
|
```
|
|
245
|
-
|
|
309
|
+
|
|
310
|
+
|
|
246
311
|
|
|
247
312
|
## Contributing
|
|
248
313
|
|
|
249
314
|
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
|
|
250
315
|
|
|
251
|
-
|
|
316
|
+
|
|
317
|
+
|
|
252
318
|
## License
|
|
253
319
|
|
|
254
320
|
[MIT](https://choosealicense.com/licenses/mit/)
|
|
255
|
-
|