useGlobalState()
import { useGlobalState } from '@dr.pogodin/react-global-state';
The primary hook for interacting with the GlobalState, modeled after
the standard React's
useState().
It subscribes a component to a given path
of global state, and provides
a function to update it. Each time the value at path
changes, the hook
triggers re-render of its host component.
For performance, the library does not copy objects written to / read from global state paths. You MUST NOT manually mutate returned state values, or change objects already written into the global state, without explicitly clonning them first yourself.
State update notifications are asynchronous. When your code does multiple global state updates in the same React rendering cycle, all state update notifications are queued and dispatched together, after the current rendering cycle. In other words, in any given rendering cycle the global state values are "fixed", and all changes becomes visible at once in the next triggered rendering pass.
The TypeScript signature of useGlobalState() implementation is
function useGlobalState(
path?: null | string,
initialValue?: ValueOrInitializerT<unknown>,
): UseGlobalStateResT<any>
however, it is on purpose shadowed by the following TypeScript overloads, to make convenient and safe static type analysis possible.
TypeScript Overloads
-
The first overload for this hook has the signature
function useGlobalState<StateT>(): UseGlobalStateResT<StateT>;
where
StateT
— The type of global state content.
In other words, when called without arguments, the hook gives access to reading / writing the entire global state as a whole.
-
The second overload is (simplified by omitting the exact details behind DataT definition):
function useGlobalState<
StateT,
PathT extends null | string | undefined,
>(
path: PathT,
initialValue?: ValueOrInitializerT<DataT>
): UseGlobalStateResT<DataT>;with two generic parameters:
StateT
— The type of global state content.PathT
— null | string | undefined — The type ofpath
argument.
The type DataT is auto-evaluated by TypeScript based on generic parameters, if possible, and used to type-check the loader and result. If DataT cannot be auto-evaluated, it falls back to void, which forbids TypeScript to use this overload.
tipAs StateT cannot be evaluated from hook argument / result types, to use this hook overload directly one would need to provide both generic parameters explictly:
useGlobalState<StateT, typeof path>(path);
Instead, you should prefer to use withGlobalStateType() function to get and use a specially wrapped version of this hook, with "locked-in" StateT type, which allows TS to auto-evaluate PathT based on
path
argument, and thus allows to use this hook variant without generic parameters, when possible:const { useGlobalState } = withGlobalStateType<StateT>();
// Behind the scene, TS still auto-evaluates DataT type, and uses it
// for type checks; it also denies to compile it, if DataT cannot be
// evaluated.
useGlobalState(path); -
Another overload permits to force any DataT type under the caller's discretion (simplified by omitting details behind the exact DataT definition):
function useGlobalState<
Forced extends ForceT | false = false,
ValueT = void,
>(
path: null | string | undefined,
initialValue?: ValueOrInitializerT<ValueT>,
): UseGlobalStateResT<ValueT>;Generic parameters are:
Unlocked
— ForceT | false — The default value, false, forbids TypeScript to use this overload (it does so by forcing DataT to evaluate as void). It must be set equal ForceT explicitly to use this overload.ValueT
— The type of value at the statepath
, defaults to void to force the caller to specify it.
Arguments
-
path
— null | string | undefined — Dot-delimitered state path. It can be null or undefined to subscribe for entire state as a whole. Under-the-hood state values are read and written using Lodash's _.get() and _.set() methods, thus it is safe to access state paths which have not been created before (in JS, in TS the static typing will forbid it if StateT is well-defined). -
initialValue
— ValueOrInitializerT<ValueT> — Initial value to set at thepath
, or initializer function for this value:- If a function is given, it will act similar to
the lazy initial state of the standard React's useState().
only if the value at
path
is undefined, the function will be executed, and the value it returns will be written to thepath
. - Otherwise, the given value itself will be written to the
path
, if the current value atpath
is undefined.
- If a function is given, it will act similar to
the lazy initial state of the standard React's useState().
only if the value at
Result
It returns an array with two elements [value, setValue]
(see the type
UseGlobalStateResT<ValueT>):
-
value
— ValueT — The current value at the givenpath
. -
setValue
— SetterT<ValueT> — The setter function to update the value atpath
.Similar to the standard React's
useState()
, it supports functional value updates: ifsetValue()
is called with a function as argument, that function will be called and its return value will be written topath
. Otherwise, the argument ofsetValue()
itself is written topath
.Also, similar to the standard React's state setters,
setValue()
is a stable function: it does not change between component re-renders.