Skip to content

Instantly share code, notes, and snippets.

@abbott
Last active January 21, 2024 03:23
Show Gist options
  • Save abbott/02a9fbf81d05e0f67c1120111d0f3d2c to your computer and use it in GitHub Desktop.
Save abbott/02a9fbf81d05e0f67c1120111d0f3d2c to your computer and use it in GitHub Desktop.
Global state provider using Context API in React.js
import { createContext, useContext, useMemo } from 'react';
import { useLocalStorage } from './local-storage';
import { getOs, getBrowser } from '@lib/utils';
import { SITE } from '@data/constants';
export const GlobalContext = createContext();
const date = new Date().toISOString();
const os = getOs().toLowerCase();
const browser = getBrowser().toLowerCase();
const initState = {
date,
os,
browser,
user: undefined,
dark: SITE.DARK,
banner: SITE.BANNER,
animate: SITE.ANIMATE,
storage: false,
};
export const reducer = (gstate, action) => {
switch (action.type) {
case 'RESET':
return initState;
case 'INIT':
return { ...gstate, ...action.payload.clientState, ...action.payload.storageReturn };
case 'STORAGE':
return { ...gstate, ...action.payload };
case 'SET_OS':
return { ...gstate, os: action.payload };
case 'SET_BROWSER':
return { ...gstate, browser: action.payload };
case 'SET_USER':
return { ...gstate, user: action.payload };
case 'SET_ANIMATE':
return { ...gstate, animate: action.payload };
case 'SET_DARK':
return { ...gstate, dark: action.payload };
case 'SET_BANNER':
return { ...gstate, banner: action.payload };
case 'TOGGLE_BANNER':
return { ...gstate, banner: !gstate.banner };
case 'TOGGLE_DARK':
return { ...gstate, dark: !gstate.dark };
default:
throw new Error(`Unhandled action type: ${action.type}`);
}
};
export const GlobalProvider = ({ children }) => {
const [gstate, dispatch] = useLocalStorage('global', reducer, initState);
const contextValue = useMemo(() => ({ gstate, dispatch }), [gstate, dispatch]);
return (
<GlobalContext.Provider value={contextValue}>
{children}
</GlobalContext.Provider>
);
};
export const useGlobal = () => {
const context = useContext(GlobalContext);
if (!context) {
throw new Error('useGlobal must be used within a GlobalProvider');
}
return context;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment