Typed React Context Factory Abstraction
1 - makes out of context usage message more explicit
2 - abstracts useContext hook
3 - resolves typescripts "undefined" type problem
import { createContext, useContext } from 'react';
export function contextFactory<T extends unknown | null>() {
const context = createContext<T | undefined>(undefined);
const useCtx = () => {
const ctx = useContext(context);
if (ctx === undefined) {
throw new Error('useContext must be used inside of a Provider with a value');
}
return ctx;
};
return [useCtx, context] as const;
}
creating Provider wrapper
interface StoreContextValue {
value: string;
addValue: (value: string) => void;
}
const [useStoreContext, StoreContext] = contextFactory<StoreContextValue>();
export { useStoreContext };
interface Props {
children: ReactNode;
}
export function StoreProvider({ children }: Props) {
const [value, setValue] = useState<sting | null>(null);
const addValue = useCallback((value: string) => { setValue(value) }, []);
return (
<StoreContext.Provider value={{ value, addValue }}>
{children}
</StoreContext.Provider>
);
}