-
-
Save TimeBandit/e71f42f140fdbb2291540167a9e0a187 to your computer and use it in GitHub Desktop.
Using createContext to create a global store
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { counterState } from "./count/countActions"; | |
import { userState } from "./user/userActions"; | |
// combine initial states | |
export default interface State extends counterState, userState {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// store/useStore.js | |
// original code can be found here: https://dev.to/ramsay/build-a-redux-like-global-store-using-react-hooks-4a7n | |
import React, { Dispatch, ReactNode, useContext, useReducer } from "react"; | |
import { countActions, countInitialState } from "./countActions"; | |
import State from "./State"; | |
import { userActions, userInitialState } from "./userActions"; | |
// create context | |
interface Context { | |
state: State; | |
dispatch: Dispatch<Action>; | |
} | |
const initialState: State = { | |
...countInitialState, | |
...userInitialState, | |
}; | |
const StoreContext = React.createContext({ state: initialState } as Context); | |
// combine actions | |
const Actions = { | |
...userActions, | |
...countActions, | |
}; | |
type Action = { type: keyof typeof Actions }; | |
// create the reducer | |
const reducer = (state: State, action: Action): State => { | |
const act = Actions[action.type]; | |
const update = act(state); | |
return { ...state, ...update }; | |
}; | |
// create the provider that uses our context | |
interface ProviderProps { | |
children: ReactNode; | |
} | |
export const StoreProvider = ({ children }: ProviderProps) => { | |
const [state, dispatch] = useReducer(reducer, initialState); | |
return <StoreContext.Provider value={{ state, dispatch }}>{children}</StoreContext.Provider>; | |
}; | |
// useStore will be used in React components to fetch and mutate state | |
// this is a hook that wraps useContext | |
export const useStore = () => { | |
const { state, dispatch } = useContext(StoreContext); | |
return { state, dispatch }; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment