@dr.pogodin/react-global-state
Version:
Hook-based global state for React
66 lines (65 loc) • 4.52 kB
TypeScript
import { type Dispatch, type SetStateAction } from 'react';
import { type ForceT, type LockT, type TypeLock, type ValueAtPathT, type ValueOrInitializerT } from './utils';
export type SetterT<T> = Dispatch<SetStateAction<T>>;
export type UseGlobalStateResT<T> = [T, SetterT<T>];
/**
* The primary hook for interacting with the global state, modeled after
* the standard React's
* [useState](https://reactjs.org/docs/hooks-reference.html#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.
*
* **Note:**
* - 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.
*
* @param path Dot-delimitered state path. It can be undefined to
* subscribe for entire state.
*
* Under-the-hood state values are read and written using `lodash`
* [_.get()](https://lodash.com/docs/4.17.15#get) and
* [_.set()](https://lodash.com/docs/4.17.15#set) methods, thus it is safe
* to access state paths which have not been created before.
* @param initialValue Initial value to set at the `path`, or its
* factory:
* - If a function is given, it will act similar to
* [the lazy initial state of the standard React's useState()](https://reactjs.org/docs/hooks-reference.html#lazy-initial-state):
* only if the value at `path` is `undefined`, the function will be executed,
* and the value it returns will be written to the `path`.
* - Otherwise, the given value itself will be written to the `path`,
* if the current value at `path` is `undefined`.
* @return It returs an array with two elements: `[value, setValue]`:
*
* - The `value` is the current value at given `path`.
*
* - The `setValue()` is setter function to write a new value to the `path`.
*
* Similar to the standard React's `useState()`, it supports
* [functional value updates](https://reactjs.org/docs/hooks-reference.html#functional-updates):
* if `setValue()` is called with a function as argument, that function will
* be called and its return value will be written to `path`. Otherwise,
* the argument of `setValue()` itself is written to `path`.
*
* Also, similar to the standard React's state setters, `setValue()` is
* stable function: it does not change between component re-renders.
*/
declare function useGlobalState<Forced extends ForceT | LockT = LockT, ValueT = void>(path: null | string | undefined, initialValue?: ValueOrInitializerT<TypeLock<Forced, never, ValueT>>): UseGlobalStateResT<TypeLock<Forced, void, ValueT>>;
declare function useGlobalState<StateT>(): UseGlobalStateResT<StateT>;
declare function useGlobalState<StateT, PathT extends null | string | undefined>(path: PathT, initialValue: ValueOrInitializerT<Exclude<ValueAtPathT<StateT, PathT, never>, undefined>>): UseGlobalStateResT<Exclude<ValueAtPathT<StateT, PathT, void>, undefined>>;
declare function useGlobalState<StateT, PathT extends null | string | undefined>(path: PathT, initialValue?: ValueOrInitializerT<ValueAtPathT<StateT, PathT, never>>): UseGlobalStateResT<ValueAtPathT<StateT, PathT, void>>;
export default useGlobalState;
export interface UseGlobalStateI<StateT> {
(): UseGlobalStateResT<StateT>;
<PathT extends null | string | undefined>(path: PathT, initialValue: ValueOrInitializerT<Exclude<ValueAtPathT<StateT, PathT, never>, undefined>>): UseGlobalStateResT<Exclude<ValueAtPathT<StateT, PathT, void>, undefined>>;
<PathT extends null | string | undefined>(path: PathT, initialValue?: ValueOrInitializerT<ValueAtPathT<StateT, PathT, never>>): UseGlobalStateResT<ValueAtPathT<StateT, PathT, void>>;
<Forced extends ForceT | LockT = LockT, ValueT = unknown>(path: null | string | undefined, initialValue?: ValueOrInitializerT<TypeLock<Forced, never, ValueT>>): UseGlobalStateResT<TypeLock<Forced, void, ValueT>>;
}