Skip to content

Instantly share code, notes, and snippets.

@jackrobertscott
Created January 7, 2020 13:14
Show Gist options
  • Save jackrobertscott/3eea1f831e375df44befed987b58c8a8 to your computer and use it in GitHub Desktop.
Save jackrobertscott/3eea1f831e375df44befed987b58c8a8 to your computer and use it in GitHub Desktop.
The perfect demo of react context and local storage in one file.
import {
createElement as element,
createContext,
useContext,
FC,
ReactNode,
useState,
useMemo,
useEffect,
} from 'react'
export interface IPreferences {
theme: 'night_sky' | 'snow_storm' | 'blue_harvester'
}
export type IPreferencesContext = IPreferences & {
update: (value: Partial<IPreferences>) => void
}
export const PreferencesContext = createContext<IPreferencesContext>({
theme: 'snow_storm',
update: () => console.warn('Preferences not setup'),
})
export const Preferences: FC<{ children: ReactNode }> = ({ children }) => {
const local = 'authpack.preferences'
let initial: IPreferences = {
theme: 'snow_storm',
}
try {
const data = localStorage.getItem(local)
if (data) initial = JSON.parse(data)
} catch {
localStorage.removeItem(local)
}
const [state, stateChange] = useState<IPreferences>(initial)
useEffect(() => {
try {
const data = JSON.stringify(state)
localStorage.setItem(local, data)
} catch {
localStorage.removeItem(local)
}
}, [state])
const value = useMemo(() => {
return {
...state,
update: (data: Partial<IPreferences>) =>
stateChange({ ...state, ...data }),
}
}, [state])
return element(PreferencesContext.Provider, {
value,
children,
})
}
export const usePreferences = () => {
return useContext(PreferencesContext)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment