Skip to content

Instantly share code, notes, and snippets.

@FaberVitale
Last active August 28, 2022 13:31
Show Gist options
  • Save FaberVitale/f2ae487e2992dfbf8cfb52a5a8b62f8a to your computer and use it in GitHub Desktop.
Save FaberVitale/f2ae487e2992dfbf8cfb52a5a8b62f8a to your computer and use it in GitHub Desktop.
// @see https://kentcdodds.com/blog/how-to-use-react-context-effectively
// @see https://beta.reactjs.org/learn/scaling-up-with-reducer-and-context
import {
createContext,
Dispatch,
useReducer,
ReactNode,
useContext,
} from 'react';
type ReducerState = {};
type ReducerActions = { type: 'todo' };
const initialReducerState = {};
const reducer = (a: ReducerState) => a;
/**
* @internal
* Do not export!
*/
const DispatchContext = createContext<Dispatch<ReducerActions> | null>(null);
/**
* @internal
* Do not export!
*/
const StateContext = createContext<ReducerState | null>(null);
export interface ContextModuleProviderProps {
children: ReactNode;
}
export function useContextDispatch() {
const dispatch = useContext(DispatchContext);
if (!dispatch) {
throw new Error('useContextDispatch, missing context provider');
}
return dispatch;
}
export function useContextState() {
const state = useContext(StateContext);
if (!state) {
throw new Error('useContextState, missing context provider');
}
return state;
}
export function ContextModuleProvider({ children }: ContextModuleProviderProps) {
const [ctxState, dispatch] = useReducer(reducer, initialReducerState);
return (
<StateContext.Provider value={ctxState}>
<DispatchContext.Provider value={dispatch}>
{children}
</DispatchContext.Provider>
</StateContext.Provider>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment