UNPKG

@dr.pogodin/react-global-state

Version:
66 lines (65 loc) 4.52 kB
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>>; }