UNPKG

@ehsaneha/react-observable-store

Version:

This is an extension of the `@ehsaneha/observable-store` library specifically tailored for React applications inspired by `zustand` library.

106 lines (105 loc) 4.39 kB
import React from "react"; import { ObservableStoreClass, } from "@ehsaneha/observable-store"; import isEqual from "lodash.isequal"; export * from "./types"; // export const isInComponent = () => { // let _result = false; // try { // React.useRef(null); // _result = true; // } catch (_) {} // return _result; // }; export class ReactObservableStoreClass extends ObservableStoreClass { constructor() { // onChange = ( // observer: Observer<S | undefined>, // deps?: ObserverDeps<S | undefined> // ) => { // if (isInComponent()) { // React.useEffect(() => { // const obj = { observer, deps }; // this.addObserver(obj); // return () => this.removeObserver(obj); // }, []); // } else { // this.onChange(observer, deps); // } // }; super(...arguments); this.useOnChange = (observer, deps) => { React.useEffect(() => { // const obj = { observer, deps }; // this.addObserver(obj); // return () => this.removeObserver(obj); const removeObserver = this.onChange(observer, deps); return () => removeObserver(); }, []); }; this.useGet = (func) => { const [state] = this.useState(func); return state; }; this.useState = (func, useEffectDeps = [], onChangeDeps) => { const [state, _setState] = React.useState(func ? func(this.get(), undefined, undefined) : this.get()); const _getState = (storeState, localPrevState) => { const _newLocalState = func ? func(storeState, localPrevState, this.get()) : storeState; return isEqual(_newLocalState, localPrevState) ? localPrevState : _newLocalState; }; this.useOnChange((v) => _setState((s) => _getState(v, s)), onChangeDeps); React.useEffect(() => { _setState((s) => _getState(this.get(), s)); }, useEffectDeps); return [state, this.set, _setState]; }; // useSubStore = <S, TActions extends Actions, SubState>( // subFunc?: (state: S) => SubState, // actions?: CreateActionsFunc<S | undefined, TActions> // ): Store<SubState, TActions> => { // const themeStore = useStore({ // themeColor: _currentUserContext.userStore.get()?.themeColor ?? "#11296b", // bgImage: _currentUserContext.userStore.get()?.bgImage ?? null, // }); // _currentUserContext.userStore.useOnChange( // (user) => { // themeStore.set({ // themeColor: user?.themeColor ?? "#11296b", // bgImage: user?.bgImage ?? null, // }); // }, // (s) => [s?.themeColor, s?.bgImage] // ); // }; // useBind = <S, TActions extends Actions, SubState>( // func?: (state: S) => void, // actions?: CreateActionsFunc<S | undefined, TActions> // ): Store<SubState, TActions> => { // const getCanSubmit = () => { // return ( // submitErrorsStore.get() === null && // isEmpty(localErrorsStore.get()) && // (allowInitSubmit || // stringify(initData()) !== stringify(dataStore.get())) // ); // }; // const canSubmit = () => { // canSubmitStore.set(getCanSubmit()); // }; // const canSubmitStore = useStore(getCanSubmit()); // submitErrorsStore.useOnChange(canSubmit); // localErrorsStore.useOnChange(canSubmit); // dataStore.useOnChange(canSubmit); // }; } } export const createStore = (initState, actions) => { const _store = new ReactObservableStoreClass(initState); return Object.assign(_store, actions === null || actions === void 0 ? void 0 : actions(Object.assign({}, _store))); }; export const useStore = (initState, actions) => { return React.useMemo(() => createStore(initState, actions), []); };