import type { ImmerHook, Updater } from './useImmer';
import { freeze, produce } from 'immer';
import { useState } from 'react';
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
import { useUnmount } from './useUnmount';
interface GlobalStateHook<S> {
(): ImmerHook<S>;
readonly state: S;
setState: Updater<S>;
}
* @deprecated since version 19, try to use `rcl-store`
*/
export function createGlobalState<S>(): GlobalStateHook<S | undefined>;
export function createGlobalState<S>(initialValue: S): GlobalStateHook<S>;
export function createGlobalState<S>(initialValue?: S): GlobalStateHook<S | undefined> {
const store = {
state: freeze(typeof initialValue === 'function' ? initialValue() : initialValue, true),
setState(updater: any) {
if (typeof updater === 'function') {
store.state = produce(store.state, updater);
} else {
store.state = freeze(updater);
}
for (const update of store.updates) {
update(store.state);
}
},
updates: new Set<(...args: any[]) => any>(),
};
return new Proxy(
() => {
const [state, setState] = useState(store.state);
useIsomorphicLayoutEffect(() => {
if (!store.updates.has(setState)) {
store.updates.add(setState);
}
});
useUnmount(() => {
store.updates.delete(setState);
});
return [state, store.setState];
},
{
get(target, prop, receiver) {
if (prop === 'state') {
return store.state;
}
if (prop === 'setState') {
return store.setState;
}
return Reflect.get(target, prop, receiver);
},
}
) as any;
}