import { useMemo, useState, useEffect, useCallback, Dispatch, SetStateAction } from "react"; export type StateDB = [Selected, Dispatch>]; export function useDBRaw({ initialState, getter, setter: setterRaw, selector, }: { initialState: State; getter: () => Promise; setter: (val: State) => Promise | void; selector: (state: State) => Selected; }): StateDB { const [state, setState] = useState(initialState); useEffect(() => { getter().then(state => { if (!state) { setterRaw(initialState); return; } setState(state); }); // Run once on mount // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const setter = useCallback( async newState => { const val = typeof newState === "function" ? newState(await getter()) : newState; setState(val); return setterRaw(val); }, [getter, setterRaw], ); const result = useMemo(() => selector(state), [state, selector]); return [result, setter]; }