Created
January 7, 2020 13:14
-
-
Save jackrobertscott/3eea1f831e375df44befed987b58c8a8 to your computer and use it in GitHub Desktop.
The perfect demo of react context and local storage in one file.
This file contains hidden or 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 { | |
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