yezyilomo / state-pool

Transform your React app with our state management library! Declare global and local states like variables, powered by the magic of React hooks 🪄✨
https://yezyilomo.github.io/state-pool/
MIT License
142 stars 17 forks source link

Return state object reference in `useState` & `useReducer` hooks #177

Closed yezyilomo closed 1 year ago

yezyilomo commented 1 year ago

When dealing with global state it’s very easy to get a reference to a state object because you have a full control from instantiating it to using it, but when you’re dealing with local state it's impossible to get the reference because all the instantiation and hooking are done within useState or useReducer hook. So we need to find a way to get a reference to the state object.

Here is a proposed API

const [state, setState, updateState, stateObject] = useState()
const [state, dispatch, stateObject] = useReducer()

State object is returned as the last element of the array because it’s rarely going to be used but sometimes it’s really needed. So with this API users can still use [state, setState, updateState] or [state, dispatch] and assume stateObject never existed

yezyilomo commented 1 year ago

More reason to implement this. It will allow us to move this code to useReducer and let it handle local state instantiation https://github.com/yezyilomo/state-pool/blob/6d4cae96463747f02c8cf5a34291b3a4ed68f4b5/src/useState.ts#L49-L66

Right now both useState and useReducer has this code block which doesn’t feel right since useState is just a special case of useReducer.

We can put this code in a hook named useStateRef because what it does is simply returning a reference to state object which might either be global or local, i.e

function useStateObjectRef(state){
    const localStateRef = React.useMemo(() => {
        if (state instanceof State) {
            return null;
        }
        else {
            return createState(state);  // Hold a reference to a local state
        }
    }, [])

    let _state: State<unknown>;
    if (localStateRef instanceof State) {
        _state = localStateRef;
    }
    else {
        _state = state as State<unknown>;
    }
}
yezyilomo commented 1 year ago

For consistency reason, this API has to be implemented in store API too. i.e

const [state, setState, updateState, stateObject] = store.useState()

const [state, dispatch, stateObject] = store.useReducer()