react-global-state-hooks 1.0.14 → 1.0.16

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 CHANGED
@@ -1,86 +1,113 @@
1
1
  # react-global-state-hooks
2
- This is a package to easily handling global-state across your react-components **No-redux**, **No-context**
3
2
 
4
- This utility follows the same style as the default **useState** hook, with a subscription pattern and **HOFs** to create a more intuitive, atomic and easy way of sharing state between components
3
+ This is a package to easily handling global-state across your react components
5
4
 
6
- ## Creating a global store, an a simple hook
5
+ This utility uses the **useState** hook within a subscription pattern and **HOFs** to create a more intuitive, atomic and easy way of sharing state between components
7
6
 
8
- We are gonna create a global count example **count.ts**:
7
+ ...
9
8
 
10
- ```JSX
11
- // Import the store costructor
12
- import GlobalStore from 'react-global-state-hooks';
9
+ ...
10
+
11
+ # Creating a global store
12
+
13
+ We are gonna create a global count example **useCountGlobal.ts**:
14
+
15
+ ```ts
16
+ import { GlobalStore } from 'react-global-state-hooks';
13
17
 
14
18
  // initialize your store with the default value of the same.
15
19
  const countStore = new GlobalStore(0);
16
20
 
17
- // you'll use this function the same way you'll use the **useState**
21
+ // get the hook
18
22
  export const useCountGlobal = countStore.getHook();
19
23
 
24
+ // inside your component just call...
25
+ const [count, setCount] = useCountGlobal(); // no paremeters are needed since this is a global store
26
+
20
27
  // That's it, that's a global store... Strongly typed, with a global-hook that we could reuse cross all our react-components.
28
+
29
+ // #### Optionally you are able to use a decoupled hook,
30
+ // #### This function is linked to the store hooks but is not a hook himself.
31
+
32
+ export const [getCount, sendCount] = countStore.getHookDecoupled();
33
+
34
+ // @example
35
+ console.log(getCount()); // 0;
36
+
37
+ // components subscribed to the global hook if there are so
38
+ sendCount(5);
39
+
40
+ console.log(getCount()); // 5;
21
41
  ```
22
42
 
23
- ## Implementing your global hook into your components
24
- Let's say we have two components **MyFirstComponent**, **MySecondComponent**, in order to use our global hook they will look just like:
43
+ ...
44
+
45
+ ...
46
+
47
+ # Implementing your global hook into your components
48
+
49
+ Let's say we have two components **MyFirstComponent**, **MySecondComponent**, in order to use our global hook they will look just like:
25
50
 
26
51
  ```JSX
27
- import { useCountGlobal } from './count'
52
+ import { useCountGlobal } from './useCountGlobal'
28
53
 
29
54
  const MyFirstComponent: React.FC = () => {
30
55
  const [count, setter] = useCountGlobal();
31
- const onClick = useCallback(() => setter(currentState => currentState + 1), []);
56
+ const onClickAddOne = () => setter(count + 1);
32
57
 
33
- return (<button onclick={onClick}>count: {count}<button/>);
58
+ return (<button onClick={onClickAddOne}>{`count: ${count}`}</button>);
34
59
  }
35
60
 
36
61
  const MySecondComponent: React.FC = () => {
37
62
  const [count, setter] = useCountGlobal();
38
- const onClick = useCallback(() => setter(currentState => currentState + 1));
39
63
 
40
- return (<button onclick={onClick}>count: {count}<button/>);
64
+ // it can also be use as a normal setter into a callback or other hooks
65
+ const onClickAddTwo = useCallback(() => setter(state => state + 2), [])
66
+
67
+ return (<button onClick={onClickAddOne}>{`count: ${count}`}</button>);
41
68
  }
42
69
 
43
- // Just like that! You are now using a global state!!
70
+ // It's so simple to share information between components
44
71
  ```
45
72
 
46
73
  Note that the only difference between this and the default **useState** hook is that you are not adding the initial value, cause you already did that when you created the store:
47
74
 
48
- ```JSX
75
+ ```ts
49
76
  const countStore = new GlobalStore(0);
50
77
  ```
51
78
 
52
- ## Persisted store
79
+ ...
53
80
 
54
- You could persist the state with **local-storage** by just adding the **storage-key** to the constructor of your global-store, for example:
81
+ ...
55
82
 
56
- ```JSX
57
- // The FIRST parameter is the initial value of the state
58
- // The Second parameter is an API to restrict access to the state, will talk about that later on [README]:./README.advance.md
59
- // The Third parameter is the key that will be used on the local-storage
60
- const countStore = new GlobalStore(0, null, 'GLOBAL_COUNT');
61
- ```
83
+ # Persisting state into localhost
62
84
 
63
- ## Consuming Persisted Store
85
+ if you want to persist the value of the store into the. **localstorage**, you only have to add the property **localStorageKey** into the configuration parameter.
64
86
 
65
- ```JSX
66
- const MyComponent: React.FC = () => {
67
- // connect the component to the global persisted storage
68
- const [count, setCount] = useCountGlobal();
69
- const onClickAddOne = () => setCount(count + 1);
87
+ ```ts
88
+ const countStore = new GlobalStore(0, {
89
+ localStorageKey: 'my_persisted_state',
70
90
 
71
- return (<button onclick={onClickAddOne}>count: {count}<button/>);
72
- }
91
+ // by default, the state is encrypted to base64, but you can disable it, or use a custom encryptor
92
+ encrypt: false,
93
+
94
+ // by default, the state is encrypted to base64, but you can disable it, or use a custom decrypt
95
+ decrypt: false,
96
+ });
73
97
  ```
74
98
 
75
- ## Decoupled hook
99
+ ...
76
100
 
77
- If you want to access the global state outside a component or outside a hook, or without subscribing the component to the state changes...
101
+ ...
78
102
 
79
- This is especially useful when you want to create components that have edition access to a certain store, but they actually don't need to be reactive to the state changes, like a search component that just need to get the current state every time that is going to search the data; but actually don't need to be subscribed to the changes over the collection he is going to be filtering.
103
+ # Decoupled hook
80
104
 
105
+ If you want to access the global state outside a component or outside a hook, or without subscribing the component to the state changes...
81
106
 
82
- ```JSX
83
- import GlobalStore from 'react-global-state-hooks';
107
+ This is especially useful when you want to create components that have edition access to a certain store, but they actually don't need to be reactive to the state changes, like a search component that just need to get the current state every time that is going to search the data; but actually don't need to be subscribed to the changes over the collection he is going to be filtering.
108
+
109
+ ```ts
110
+ import { GlobalStore } from 'react-global-state-hooks';
84
111
 
85
112
  const countStore = new GlobalStore(0);
86
113
 
@@ -88,14 +115,15 @@ const countStore = new GlobalStore(0);
88
115
  export const useCountGlobal = countStore.getHook();
89
116
 
90
117
  // this functions are not hooks, and they can be used in whatever place into your code, ClassComponents, OtherHooks, Services etc.
91
- export const [getCountGlobalValue, setCountGlobalValue] = countStore.getHookDecoupled();
92
-
118
+ export const [getCount, sendCount] = countStore.getHookDecoupled();
93
119
  ```
94
120
 
95
- Let's see a trivial example:
121
+ Let's see a trivial example:
122
+
123
+ ...
96
124
 
97
125
  ```JSX
98
- import { useCountGlobal, setCountGlobalValue } from './useCountGlobal'
126
+ import { useCountGlobal, sendCount } from './useCountGlobal'
99
127
 
100
128
  const CountDisplayerComponent: React.FC = () => {
101
129
  const [count] = useCountGlobal();
@@ -103,32 +131,562 @@ const CountDisplayerComponent: React.FC = () => {
103
131
  return (<label>{count}<label/>);
104
132
  }
105
133
 
134
+ // here we have a separate component that is gonna handle the state of the previous component we created,
135
+ // this new component is not gonna be affected by the changes applied on <CountDisplayerComponent/>
106
136
  // Stage2 does not need to be updated once the global count changes
107
137
  const CountManagerComponent: React.FC = () => {
108
- const increaseClick = () => setCountGlobalValue(count => count + 1);
109
- const decreaseClick = () => setCountGlobalValue(count => count - 1);
138
+ const increaseClick = useCallback(() => sendCount(count => count + 1), []);
139
+ const decreaseClick = useCallback(() => sendCount(count => count - 1), []);
110
140
 
111
141
  return (<>
112
- <button onclick={increaseClick}>increase<button/>
113
- <button onclick={decreaseClick}>decrease<button/>
142
+ <button onClick={increaseClick} >increase</button>
143
+ <button onClick={decreaseClick} >decrease</button>
114
144
  </>);
115
145
  }
116
146
  ```
117
147
 
118
- ## Advance Config
119
- Here you can see more information how to create more complex services for your global stores.
120
- [README]:./README.advance.md
148
+ ...
149
+
150
+ ...
151
+
152
+ # Restricting the manipulation of the global **state**
153
+
154
+ ## Who hate reducers?
155
+
156
+ It's super common to have the wish or the necessity of restricting the manipulation of the **state** through a specific set of actions or manipulations...**Dispatches**? **Actions**? Let's make it simple BY adding a custom **API** to the configuration of our **GlobalStore**
157
+ ...
158
+
159
+ ```ts
160
+ const initialValue = 0;
161
+
162
+ const config = {
163
+ // this is not reactive information that you could also store in the async storage
164
+ // upating the metadata will not trigger the onStateChanged method or any update on the components
165
+ metadata: null,
166
+
167
+ // The lifecycle callbacks are: onInit, onStateChanged, onSubscribed and computePreventStateChange
168
+ };
169
+
170
+ const countStore = new GlobalStore(
171
+ initialValue,
172
+ config,
173
+ {
174
+ log: (message: string) => (): void => {
175
+ console.log(message);
176
+ },
177
+
178
+ increase(message: string) {
179
+ return (storeTools: StoreTools<number>) => {
180
+ this.log(message);
181
+
182
+ return storeTools.getState();
183
+ };
184
+ },
185
+
186
+ decrease(message: string) {
187
+ return (storeTools: StoreTools<number>) => {
188
+ this.log(message);
189
+
190
+ return storeTools.getState();
191
+ };
192
+ },
193
+ } as const // the -as const- is necessary to avoid typescript errors
194
+ );
195
+
196
+ // the way to get the hook is the same as for simple setters
197
+ const useCountStore = countStore.getHook();
198
+
199
+ // now instead of a setState method, you'll get an actions object
200
+ // that contains all the actions that you defined in the setterConfig
201
+ const [count, countActions] = useCountStore();
202
+
203
+ // count is the current state - 0 (number)
204
+ // countActions is an object that contains all the actions that you defined in the setterConfig
205
+ // countActions.increase(); // this will increase the count by 1, returns the new count (number)
206
+ // countActions.decrease(); // this will decrease the count by 1, returns the new count (number)
207
+ ```
208
+
209
+ ...
210
+
211
+ # Configuration callbacks
212
+
213
+ ## config.onInit
214
+
215
+ This method will be called once the store is created after the constructor,
216
+
217
+ @examples
218
+
219
+ ```ts
220
+ import { GlobalStore } from 'react-global-state-hooks';
221
+
222
+ const initialValue = 0;
223
+
224
+ const store = new GlobalStore(0, {
225
+ onInit: async ({ setMetadata, setState }) => {
226
+ const data = await someApiCall();
227
+
228
+ setState(data);
229
+ setMetadata({ isDataUpdated: true });
230
+ },
231
+ });
232
+ ```
233
+
234
+ ...
235
+
236
+ ## config.onStateChanged
237
+
238
+ This method will be called every time the state is changed
239
+
240
+ @examples
241
+
242
+ ```ts
243
+ import { GlobalStore } from 'react-global-state-hooks';
244
+
245
+ const store = new GlobalStore(0, {
246
+ onStateChanged: ({ getState }) => {
247
+ const state = getState();
248
+
249
+ console.log(state);
250
+ },
251
+ });
252
+ ```
253
+
254
+ ...
255
+
256
+ ## config.onSubscribed
257
+
258
+ This method will be called every time a component is subscribed to the store
259
+
260
+ @examples
261
+
262
+ ```ts
263
+ import { GlobalStore } from 'react-global-state-hooks';
264
+
265
+ const store = new GlobalStore(0, {
266
+ onSubscribed: ({ getState }) => {
267
+ console.log('A component was subscribed to the store');
268
+ },
269
+ });
270
+ ```
271
+
272
+ ...
273
+
274
+ ## config.computePreventStateChange
275
+
276
+ This method will be called every time the state is going to be changed, if it returns true the state won't be changed
277
+
278
+ @examples
279
+
280
+ ```ts
281
+ import { GlobalStore } from 'react-global-state-hooks';
282
+
283
+ const store = new GlobalStore(0, {
284
+ computePreventStateChange: ({ getState }) => {
285
+ const state = getState();
286
+ const shouldPrevent = state < 0;
287
+
288
+ if (shouldPrevent) return true;
289
+
290
+ return false;
291
+ },
292
+ });
293
+ ```
294
+
295
+ ...
296
+
297
+ ...
298
+
299
+ ...
300
+
301
+ ...
302
+
303
+ ...
304
+
305
+ # Examples and Comparison:
306
+
307
+ ## 1. Lets try to share some state between components
308
+
309
+ ### **With the GlobalStore approach, it will look like this:**
310
+
311
+ ```tsx
312
+ type TUser = {
313
+ name: string;
314
+ email: string;
315
+ };
316
+
317
+ const useUserStore = new GlobalStore<TUser>({
318
+ name: null,
319
+ email: null,
320
+ }).getHook();
321
+
322
+ const Component = () => {
323
+ const [currentUser] = useUserStore();
324
+
325
+ return <Text>{currentUser.name}</Text>;
326
+ };
327
+ ```
328
+
329
+ ## Simple, right?
330
+
331
+ ### Let's now see how this same thing would look like by using context:
332
+
333
+ ```tsx
334
+ type TUser = {
335
+ name: string;
336
+ email: string;
337
+ };
338
+
339
+ const UserContext = createContext<{
340
+ currentUser: TUser;
341
+ }>({
342
+ currentUser: null,
343
+ });
344
+
345
+ const UserProvider: React.FC<PropsWithChildren> = ({ children }) => {
346
+ const [currentUser, setCurrentUser] = useState<TUser>(null);
347
+
348
+ // ...get current user information
349
+
350
+ return (
351
+ <UserContext.Provider value={{ currentUser }}>
352
+ {children}
353
+ </UserContext.Provider>
354
+ );
355
+ };
356
+
357
+ const Component = () => {
358
+ const { currentUser } = useContext(UserContext);
359
+
360
+ return <Text>{currentUser.name}</Text>;
361
+ };
362
+
363
+ const App = () => {
364
+ return (
365
+ <UserProvider>
366
+ <Component />
367
+ </UserProvider>
368
+ );
369
+ };
370
+ ```
371
+
372
+ ### We already are able to notice a couple of extra lines right?
373
+
374
+ Let's now add another simple store to the equation
375
+
376
+ ### **With the GlobalStore approach, it will look like this:**
377
+
378
+ ```tsx
379
+ type TUser = {
380
+ name: string;
381
+ email: string;
382
+ };
383
+
384
+ const useUserStore = new GlobalStore<TUser>({
385
+ name: null,
386
+ email: null,
387
+ }).getHook();
388
+
389
+ // we create the store
390
+ const useCountStore = new GlobalStore(0).getHook();
391
+
392
+ const Component = () => {
393
+ const [currentUser] = useUserStore();
394
+
395
+ // from the component we consume the new store
396
+ const [count, setCount] = useCountStore();
397
+
398
+ return <label>{currentUser.name}</label>;
399
+ };
400
+ ```
401
+
402
+ With context, we'll have again to create all the boilerplate, and wrap the component into the new provider...
403
+
404
+ ### **Lets see that**
405
+
406
+ ```tsx
407
+ type TUser = {
408
+ name: string;
409
+ email: string;
410
+ };
411
+
412
+ const UserContext = createContext<{
413
+ currentUser: TUser;
414
+ }>({
415
+ currentUser: null,
416
+ });
417
+
418
+ // let's create the context
419
+ const CountContext = createContext({
420
+ count: 0,
421
+ setCount: (() => {
422
+ throw new Error('not implemented');
423
+ }) as Dispatch<SetStateAction<number>>,
424
+ });
425
+
426
+ const UserProvider: React.FC<PropsWithChildren> = ({ children }) => {
427
+ const [currentUser, setCurrentUser] = useState<TUser>(null);
428
+
429
+ // ...
430
+
431
+ return (
432
+ <UserContext.Provider value={{ currentUser }}>
433
+ {children}
434
+ </UserContext.Provider>
435
+ );
436
+ };
437
+
438
+ // we also need another provider
439
+ const CountProvider: React.FC<PropsWithChildren> = ({ children }) => {
440
+ const [count, setCount] = useState(0);
441
+
442
+ return (
443
+ <CountContext.Provider value={{ count, setCount }}>
444
+ {children}
445
+ </CountContext.Provider>
446
+ );
447
+ };
448
+
449
+ // we need to wrap the component into the new provider (this is for each future context)
450
+ const App = () => {
451
+ return (
452
+ <UserProvider>
453
+ <CountProvider>
454
+ <Component />
455
+ </CountProvider>
456
+ </UserProvider>
457
+ );
458
+ };
459
+
460
+ const Component = () => {
461
+ const { currentUser } = useContext(UserContext);
462
+
463
+ // finally we are able to get access to the new context...
464
+ const { count, setCount } = useContext(CountContext);
465
+
466
+ return <label>{currentUser.name}</label>;
467
+ };
468
+ ```
469
+
470
+ In this example, we are able to see how every time along with creating a good amount of repetitive code, we also have to wrap the necessary components into the Provider... Also, notice how every time we need to modify the **App** component, even when the App component is not gonna use the new state.
471
+
472
+ ### Let's make this a little more complex, now I want to implement custom methods for manipulating the count state, I also want to have the ability to modify the count state **without** having to be subscribed to the changes of the state... have you ever done that?
473
+
474
+ This is a common scenery, and guess what? in the **context** examples, we'll have to create another context, another provider, wrap and everything again...
475
+
476
+ ## Let's see this time first the **context** approach
477
+
478
+ ```tsx
479
+ type TUser = {
480
+ name: string;
481
+ email: string;
482
+ };
483
+
484
+ const UserContext = createContext<{
485
+ currentUser: TUser;
486
+ }>({
487
+ currentUser: null,
488
+ });
489
+
490
+ // let's remove the setter from this context
491
+ const CountContext = createContext({
492
+ count: 0,
493
+ });
494
+
495
+ // lets create another context to share the actions
496
+ const CountContextSetter = createContext({
497
+ increase: (): void => {
498
+ throw new Error('increase is not implemented');
499
+ },
500
+ decrease: (): void => {
501
+ throw new Error('decrease is not implemented');
502
+ },
503
+ });
504
+
505
+ const UserProvider: React.FC<PropsWithChildren> = ({ children }) => {
506
+ const [currentUser, setCurrentUser] = useState<TUser>(null);
507
+
508
+ // ...
509
+
510
+ return (
511
+ <UserContext.Provider value={{ currentUser }}>
512
+ {children}
513
+ </UserContext.Provider>
514
+ );
515
+ };
516
+
517
+ // To don't overcomplicate the example let's just add but providers into this component, that will be enough
518
+ const CountProvider: React.FC<PropsWithChildren> = ({ children }) => {
519
+ const [count, setCount] = useState(0);
520
+
521
+ const increase = () => setCount(count + 1);
522
+ const decrease = () => setCount(count - 1);
523
+
524
+ return (
525
+ //one context is gonna share the edition of the state
526
+ <CountContext.Provider value={{ count }}>
527
+ {/* this second component will share the mutations of the state */}
528
+ <CountContextSetter.Provider value={{ increase, decrease }}>
529
+ {children}
530
+ </CountContextSetter.Provider>
531
+ </CountContext.Provider>
532
+ );
533
+ };
534
+
535
+ // Since we used the same provider we don't need to modify the **App** component, but we do are **Wrapping** everything into one more **Provider**
536
+ const App = () => {
537
+ return (
538
+ <UserProvider>
539
+ <CountProvider>
540
+ {/* lets create two componets instead of one */}
541
+ <ComponentSetter />
542
+ <Component />
543
+ </CountProvider>
544
+ </UserProvider>
545
+ );
546
+ };
547
+
548
+ const ComponentSetter = () => {
549
+ const { increase, decrease } = useContext(CountContextSetter);
550
+
551
+ return (
552
+ <>
553
+ <button onPress={increase}>Increase</button>
554
+ <button onPress={decrease}>Decrease</button>
555
+ </>
556
+ );
557
+ };
558
+
559
+ const Component = () => {
560
+ const { currentUser } = useContext(UserContext);
561
+
562
+ // finally we are able to get access to the new context...
563
+ const { count } = useContext(CountContext);
564
+
565
+ return (
566
+ <>
567
+ <label>{currentUser.name}</label>
568
+ <label>{count}</label>
569
+ </>
570
+ );
571
+ };
572
+ ```
573
+
574
+ Wow, a lot!!! just to be able to separate the mutations... and have mutations!!
575
+
576
+ ### it would be easier with the GlobalStore? Let's see.
577
+
578
+ ```tsx
579
+ type TUser = {
580
+ name: string;
581
+ email: string;
582
+ };
583
+
584
+ const useUser = new GlobalStore<TUser>({
585
+ name: null,
586
+ email: null,
587
+ }).getHook();
588
+
589
+ // let's modify the store to add custom actions, the second parameter is configuration let's just pass null for now
590
+ const countStore = new GlobalStore(0, null, {
591
+ increase() {
592
+ return ({ setState }: StoreTools<number>) => {
593
+ setState((state) => state + 1);
594
+ };
595
+ },
596
+
597
+ decrease() {
598
+ return ({ setState }: StoreTools<number>) => {
599
+ setState((state) => state - 1);
600
+ };
601
+ },
602
+ } as const);
603
+
604
+ const useCount = countStore.getHook();
605
+
606
+ // this actions don't use hooks, but are connected to the store and all the subscribers will be notified
607
+ const [, countActions] = countStore.getHookDecoupled();
608
+
609
+ // this component is not subscribed to the store, so it will not be notified when the state changes
610
+ const ComponentSetter = () => {
611
+ return (
612
+ <>
613
+ <button onPress={countActions.increase}>Increase</button>
614
+ <button onPress={countActions.decrease}>Decrease</button>
615
+ </>
616
+ );
617
+ };
618
+
619
+ // this component is subscribed to the store, so it will be notified when the state changes
620
+ const Component = () => {
621
+ const [user] = useUser();
622
+ const [count, actions] = useCount();
623
+
624
+ return (
625
+ <>
626
+ <label>{count}</label>
627
+ </>
628
+ );
629
+ };
630
+ ```
631
+
632
+ ### So let's analyze what happened
633
+
634
+ To restrict the state manipulations with the custom actions, we just need to add a third parameter to the store.
635
+
636
+ ```ts
637
+ const countStore = new GlobalStore(0, null, {
638
+ log: (action: string) => () => console.log(action),
639
+
640
+ // every action is a function that returns a function that receives the store tools
641
+ increase() {
642
+ return ({ setState, getState }: StoreTools<number>): number => {
643
+ setState((state) => state + 1);
644
+
645
+ // actions are able to communicate between them
646
+ this.log('increase');
647
+
648
+ return getState();
649
+ };
650
+ },
651
+ } as const);
652
+
653
+ // the const is necessary to avoid typescript errors
654
+ ```
655
+
656
+ All the library is strongly typed, we use generics to return the correct data type in each action.
657
+
658
+ ```ts
659
+ const [, actions] = countStore.getHookDecoupled();
660
+
661
+ // for example the type of actions.increase will be: () => number
662
+ // just in case, even the parameters of the actions are gonna be exposed through TS
663
+ ```
664
+
665
+ ## getHookDecoupled
666
+
667
+ ### **getHookDecoupled** returns a tuple with the state and the actions,
668
+
669
+ This is so useful when you want to use the actions without having to be subscribed to changes of the state.
670
+ There is also a third element in the tuple which is a function for getting the metadata of the store
671
+
672
+ ### the metadata of the store is not reactive information which could be shared through the store
673
+
674
+ ## Adding metadata to the store
675
+
676
+ ```tsx
677
+ const [, , getMetadata] = new GlobalStore(0, {
678
+ metadata: {
679
+ isStoredSyncronized: false,
680
+ },
681
+ }).getHookDecoupled();
682
+
683
+ console.log(getMetadata().isStoredSyncronized); // false
684
+ ```
121
685
 
122
- ## Advantages:
123
- 1. Using REACT's simplest and default way to deal with the state.
124
- 2. Adding partial state designations (This is not on useState default functionality)
125
- 3. Added availability to create actions and decoupled access to the states, no more connects, and dispatches, just call your actions as a normal service of whatever other libraries.
126
- 4. This library is already taking care of avoiding re-renders if the new state does not have changes
127
- 5. This tool also take care for you to avoid **localStorage** data to lose the data types that you stored. For example when you are using datetimes
128
- 6. This library also is taking care of batching multiple stores updates by using **React unstable_batchedUpdates**; this is a problem that the **useState** have when you call multiple **setStates** into async flows as setTimeout
686
+ The setMetadata is part of the store tools, so it can be used in the actions, but againg the metadata is not reactive!! so it will not trigger a re-render on the subscribers
129
687
 
130
- # Finallly notes:
131
- Are concern about performance? this library is for you, instead of handling huge complex stores with options like redux, or by passing the setState to a context Provider (because of the limitations that the context has)... You should just use this library, we are using the more atomic and 'native' way that REACT gives to handle the state, and that is the hook **useState**...
688
+ ...
132
689
 
133
- This utility is just including the implementation of the use state into a subscriber pattern, to enable you to create hooks that will be subscribed to specific store changes, does how we'll be creating a global state hook.
690
+ ...
134
691
 
692
+ # That's it for now!! hope you enjoy coding!!