react-global-state-hooks 3.0.8 → 3.1.0
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 +114 -0
- package/lib/src/GlobalStore.context.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -503,6 +503,120 @@ const useContacts = createGlobalState(
|
|
|
503
503
|
|
|
504
504
|
That means your data will automatically be synchronized with the local storage, and you don't need to worry about losing the type of your Maps/Sets/Dates - the store takes care of it for you.
|
|
505
505
|
|
|
506
|
+
**The ultimate blend of flexibility and control in React state management!** You can now create an isolated global state within a React context, giving each consumer of the context provider a unique state instance. But that’s not all...
|
|
507
|
+
|
|
508
|
+
**Stateful Context with Actions** extends the powerful features of global hooks into the realm of React Context. By integrating global hooks within a context, you bring all the benefits of global state management—such as modularity, selectors, derived states, and actions—into a context-specific environment. This means each consumer of the context not only gets a unique state instance but also inherits all the advanced capabilities of global hooks.
|
|
509
|
+
|
|
510
|
+
## Creating a Stateful Context
|
|
511
|
+
|
|
512
|
+
Forget about the boilerplate of creating a context... with **createStatefulContext** it's straightforward and powerful. You can create a context and provider with one line of code.
|
|
513
|
+
|
|
514
|
+
```tsx
|
|
515
|
+
export const [useCounterContext, CounterProvider] = createStatefulContext(2);
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
Then just wrap the components you need with the provider:
|
|
519
|
+
|
|
520
|
+
```tsx
|
|
521
|
+
<CounterProvider>
|
|
522
|
+
<MyComponent />
|
|
523
|
+
</CounterProvider>
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
And finally, access the context value with the generated custom hook:
|
|
527
|
+
|
|
528
|
+
```tsx
|
|
529
|
+
const MyComponent = () => {
|
|
530
|
+
const [useCounter] = useCounterContext();
|
|
531
|
+
|
|
532
|
+
// If the component needs to react to state changes, simply use the hook
|
|
533
|
+
const [count, setCount] = useCounter();
|
|
534
|
+
|
|
535
|
+
return <>{count}</>;
|
|
536
|
+
};
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
What’s the advantage of this, you might ask? Well, now you have all the capabilities of the global hooks within the isolated scope of the context. For example, you can choose whether or not to listen to changes in the state:
|
|
540
|
+
|
|
541
|
+
```tsx
|
|
542
|
+
const MyComponent = () => {
|
|
543
|
+
const [, , setCount] = useCounterContext();
|
|
544
|
+
|
|
545
|
+
// This component can access only the setter of the state,
|
|
546
|
+
// and won't re-render if the counter changes
|
|
547
|
+
return (
|
|
548
|
+
<button onClick={() => setCount((count) => count + 1)}>Increase</button>
|
|
549
|
+
);
|
|
550
|
+
};
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
Now you have selectors—if the state changes, the component will only re-render if the selected portion of the state changes.
|
|
554
|
+
|
|
555
|
+
```tsx
|
|
556
|
+
const MyComponent = () => {
|
|
557
|
+
const [useCounter] = useCounterContext();
|
|
558
|
+
|
|
559
|
+
// Notice that we can select and derive values from the state
|
|
560
|
+
const [isEven, setCount] = useCounter((count) => count % 2 === 0);
|
|
561
|
+
|
|
562
|
+
useEffect(() => {
|
|
563
|
+
// Since the counter initially was 2 and now is 4, it’s still an even number.
|
|
564
|
+
// Because of this, the component will not re-render.
|
|
565
|
+
setCount(4);
|
|
566
|
+
}, []);
|
|
567
|
+
|
|
568
|
+
return <>{isEven ? 'is even' : 'is odd'}</>;
|
|
569
|
+
};
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**createStatefulContext** also allows you to add custom actions to control the manipulation of the state.
|
|
573
|
+
|
|
574
|
+
```tsx
|
|
575
|
+
import { createStatefulContext, StoreTools } from 'react-global-state-hooks';
|
|
576
|
+
|
|
577
|
+
type CounterState = {
|
|
578
|
+
count: number;
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
const initialState: CounterState = {
|
|
582
|
+
count: 0,
|
|
583
|
+
};
|
|
584
|
+
|
|
585
|
+
export const [useCounterContext, CounterProvider] = createStatefulContext(
|
|
586
|
+
initialState,
|
|
587
|
+
{
|
|
588
|
+
actions: {
|
|
589
|
+
increase: (value: number = 1) => {
|
|
590
|
+
return ({ setState }: StoreTools<CounterState>) => {
|
|
591
|
+
setState((state) => ({
|
|
592
|
+
...state,
|
|
593
|
+
count: state.count + value,
|
|
594
|
+
}));
|
|
595
|
+
};
|
|
596
|
+
},
|
|
597
|
+
decrease: (value: number = 1) => {
|
|
598
|
+
return ({ setState }: StoreTools<CounterState>) => {
|
|
599
|
+
setState((state) => ({
|
|
600
|
+
...state,
|
|
601
|
+
count: state.count - value,
|
|
602
|
+
}));
|
|
603
|
+
};
|
|
604
|
+
},
|
|
605
|
+
} as const,
|
|
606
|
+
}
|
|
607
|
+
);
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
And just like with regular global hooks, now instead of a setter, the hook will return the collection of actions:
|
|
611
|
+
|
|
612
|
+
```tsx
|
|
613
|
+
const MyComponent = () => {
|
|
614
|
+
const [, , actions] = useCounterContext();
|
|
615
|
+
|
|
616
|
+
return <button onClick={() => actions.increase(1)}>Increase</button>;
|
|
617
|
+
};
|
|
618
|
+
```
|
|
619
|
+
|
|
506
620
|
# Extending Global Hooks
|
|
507
621
|
|
|
508
622
|
Creating a custom builder for your **global hook** is made incredibly easy with the **createCustomGlobalState** function.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ActionCollectionConfig, createStateConfig, StateHook, StateSetter, ActionCollectionResult, StateGetter } from 'react-hooks-global-states';
|
|
3
|
+
export declare const createStatefulContext: <TState, TMetadata = null, TActions extends ActionCollectionConfig<TState, TMetadata> = null>(initialValue: TState, parameters?: createStateConfig<TState, TMetadata, TActions>) => readonly [() => [hook: StateHook<TState, keyof TActions extends never ? StateSetter<TState> : ActionCollectionResult<TState, TMetadata, TActions>, TMetadata>, getter: StateGetter<TState>, setter: keyof TActions extends never ? StateSetter<TState> : ActionCollectionResult<TState, TMetadata, TActions>], React.FC<React.PropsWithChildren<{
|
|
4
|
+
initialValue?: Partial<TState>;
|
|
5
|
+
}>>];
|
package/package.json
CHANGED