Skip to content

Commit ef7ef1a

Browse files
committed
Implement useUnfragmentedStore
1 parent 080cd64 commit ef7ef1a

File tree

4 files changed

+116
-13
lines changed

4 files changed

+116
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.DS_Store
2+
.vscode
23
node_modules
34
dist

README.md

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Fragmented Store
77
</p>
88

99
<p align="center">
10-
Tiny (~400 B) and simple (P)React <b>state management library</b>
10+
Tiny (~500 B) and simple (P)React <b>state management library</b>
1111
</p>
1212
<p align="center">
1313
Store update -> <b>only</b> components that use the updated property are rendered.
@@ -47,9 +47,9 @@ npm install fragmented-store --save
4747
```js
4848
import createStore from "fragmented-store";
4949

50-
const { Provider, useUsername, useAge } = createStore({
50+
const { Provider, useUsername, useAge, useUnfragmentedStore } = createStore({
5151
username: "Aral",
52-
age: 31
52+
age: 30
5353
});
5454

5555
export default function App() {
@@ -58,6 +58,7 @@ export default function App() {
5858
<Title />
5959
<UpdateTitle />
6060
<Age />
61+
<AllStore />
6162
</Provider>
6263
);
6364
}
@@ -76,7 +77,7 @@ function UpdateTitle() {
7677
console.log("render UpdateTitle");
7778

7879
return (
79-
<button onClick={() => setUsername((u) => u + "a")}>
80+
<button onClick={() => setUsername((s) => s + "a")}>
8081
Update {username}
8182
</button>
8283
);
@@ -85,15 +86,99 @@ function UpdateTitle() {
8586
function Age() {
8687
const [age, setAge] = useAge();
8788

88-
console.log("render Age");
89+
console.log("render age");
8990

9091
return (
9192
<div>
9293
<div>{age}</div>
93-
<button onClick={() => setAge((a) => a + 1)}>Inc age</button>
94+
<button onClick={() => setAge((s) => s + 1)}>Inc age</button>
9495
</div>
9596
);
9697
}
98+
99+
function AllStore() {
100+
const [store, update] = useUnfragmentedStore();
101+
102+
console.log({ store }); // all store
103+
104+
return (
105+
<button onClick={() => update({ age: 30, username: "Aral" })}>Reset</button>
106+
);
107+
}
108+
```
109+
110+
### Provider
111+
112+
The `Provider` is required for any of its child components to consume fragmented-store hooks.
113+
114+
```js
115+
import createStore from "fragmented-store";
116+
117+
const { Provider } = createStore({
118+
username: "Aral",
119+
age: 30
120+
});
121+
122+
function App() {
123+
return (
124+
<Provider>
125+
{/* rest */}
126+
</Provider>
127+
);
128+
}
129+
```
130+
131+
### Fragmented store
132+
133+
The power of this library is that you can use fragmented parts of the store, so if a component uses only one field of the store, it will only re-render again if there is a change in this particular field and it will not render again if the other fields change.
134+
135+
For each of the fields of the store, there is a hook with its name, examples:
136+
137+
- username 👉 `useUsername`
138+
- age 👉 `useAge`
139+
- anotherExample 👉 `useAnotherExample`
140+
141+
```js
142+
import createStore from "fragmented-store";
143+
144+
const { useUsername } = createStore({
145+
username: "Aral",
146+
age: 30
147+
});
148+
149+
function FragmentedExample() {
150+
const [username, setUsername] = useUsername();
151+
152+
return (
153+
<button onClick={() => setUsername("AnotherUserName")}>
154+
Update {username}
155+
</button>
156+
);
157+
}
158+
```
159+
160+
### Unfragmented store
161+
162+
The advantage of this library is to use the store in a fragmented way. Even so, there are cases when we want to reset the whole store or do more complex things. For these cases, we can use the hook `useUnfragmentedStore`.
163+
164+
```js
165+
import createStore from "fragmented-store";
166+
167+
const { useUnfragmentedStore } = createStore({
168+
username: "Aral",
169+
age: 30
170+
});
171+
172+
function UnfragmentedExample() {
173+
const [store, update] = useUnfragmentedStore();
174+
175+
return (
176+
<>
177+
<h1>{state.username}, {state.age}</h1>
178+
<button onClick={() => update({ age: 30, username: "Aral" })}>Reset</button>
179+
</>
180+
);
181+
}
97182
```
98183

99184
## Demo

index.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import React, { useState, useContext, createContext } from "react";
22

33
export default function createStore(store = {}) {
4-
const storeUtils = Object.keys(store).reduce((o, key) => {
5-
const fieldCapitalized = `${key[0].toUpperCase()}${key.slice(
6-
1,
7-
key.length
8-
)}`;
4+
const keys = Object.keys(store);
5+
const capitalize = (k) => `${k[0].toUpperCase()}${k.slice(1, k.length)}`;
6+
7+
const storeUtils = keys.reduce((o, key) => {
98
const context = createContext(store[key]);
109

1110
return {
1211
...o,
1312
contexts: [...(o.contexts || []), { context, key }],
14-
[`use${fieldCapitalized}`]: () => useContext(context)
13+
[`use${capitalize(key)}`]: () => useContext(context)
1514
};
1615
}, {});
1716

@@ -34,5 +33,23 @@ export default function createStore(store = {}) {
3433
return <Component>{children}</Component>;
3534
};
3635

36+
storeUtils.useUnfragmentedStore = () => {
37+
const state = {};
38+
const updates = {};
39+
keys.forEach((k) => {
40+
const [s, u] = storeUtils[`use${capitalize(k)}`]();
41+
state[k] = s;
42+
updates[k] = u;
43+
});
44+
45+
function updater(newState) {
46+
const s =
47+
typeof newState === "function" ? newState(state) : newState || {};
48+
Object.keys(s).forEach((k) => updates[k] && updates[k](s[k]));
49+
}
50+
51+
return [state, updater];
52+
};
53+
3754
return storeUtils;
3855
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"module": "dist/index.module.js",
88
"unpkg": "dist/index.umd.js",
99
"scripts": {
10-
"build": "microbundle --jsx React.createElement --no-compress --sourcemap",
10+
"build": "microbundle --jsx React.createElement",
1111
"dev": "microbundle watch",
1212
"prepublish": "yarn build"
1313
},

0 commit comments

Comments
 (0)