Last active
October 6, 2022 21:03
-
-
Save ClaireNeveu/e91f920c71058a915309bdb667aaa667 to your computer and use it in GitHub Desktop.
useSettings Skeleton
This file contains 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 { createContext, ReactChildren, useContext, useEffect, useMemo, useState } from 'react'; | |
import { Type } from 'io-ts'; | |
import { useNavigate } from 'react-router-dom-v5-compat'; | |
/* | |
* UserSettingsTable contains all the settings for a user | |
* across the application. Each key identifies a unique part | |
* of the interface to store settings for. | |
*/ | |
type UserSettingsTable = { [key: string]: any } | |
export interface SettingsConfigProp<A> { | |
defaultValue?: A; | |
skipUrlEncoding?: boolean; | |
storageKey?: string; | |
type: Type<A>; | |
} | |
export interface SettingsConfig<T> { | |
applicableRoutespace?: string; | |
settings: { [K in keyof T]: SettingsConfigProp<T[K]> }; | |
storagePath: string; | |
} | |
type UserSettingsContext = { | |
table: UserSettingsTable; | |
update: (key: string, value: any) => void | |
} | |
const UserSettings = createContext<UserSettingsContext>({ | |
table: {}, | |
update: () => { }, | |
}); | |
const SettingsProvider = ({ children }: { children: ReactChildren }) => { | |
const [settingsTable, updateSettingsTable] = useState({}); | |
const update = (key: string, value: any) => { | |
updateSettingsTable(prev => ({ ...prev, [key]: value })) | |
} | |
useEffect(() => { | |
// fetch initial settings | |
}, []); | |
return <UserSettings.Provider value={{ | |
table: settingsTable, | |
update, | |
}}>{children}</UserSettings.Provider> | |
} | |
const useSettings = <T, >(config: SettingsConfig<T>) => { | |
const { table, update } = useContext(UserSettings); | |
const [ident, reRender] = useState({}); | |
const navigate = useNavigate(); | |
const settings = useMemo(() => table[config.storagePath], [ident]); | |
const updateSettings = (updates: Partial<T>) => { | |
const newSettings = { ...settings, ...updates }; | |
update(config.storagePath, newSettings); | |
// updateDatabase <- fire and forget | |
navigate(/* new url here */ window.location.toString()) | |
reRender({}) | |
}; | |
return { updateSettings, settings } | |
} | |
export { SettingsProvider, useSettings } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment