Skip to content

Instantly share code, notes, and snippets.

@cosemansp
Created November 15, 2020 10:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cosemansp/ec3aad99cfa506e02c85058b9272926f to your computer and use it in GitHub Desktop.
Save cosemansp/ec3aad99cfa506e02c85058b9272926f to your computer and use it in GitHub Desktop.
Improved React Context
import { createContext, useContext, useMemo, ConsumerProps, ReactNode } from 'react'
interface Value {
mode: 'dark' | 'light';
setMode: (mode: 'dark' | 'light') => void;
compact: boolean;
setCompact: (compact: boolean) => void;
}
const Context = createContext<Value | null>(null)
export function useTheme(): Value {
const value = useContext(Context)
if (value === null) throw new Error('no value provided')
return value
}
export function ThemeProvider({ children }: { children: ReactNode }) {
const [mode, setMode] = useState<Value['mode']>('dark')
const [compact, setCompact] = useState<Value['compact']>(false)
const value = useMemo(() => ({
mode,
setMode,
compact,
setCompact,
}), [mode, setMode, compact, setCompact])
return <Context.Provider value={value}>{children}</Context.Provider>
}
// OPTIONAL
export function ThemeConsumer({ children }: ConsumerProps<Value>) {
const value = useTheme() // will throw if value is null
return children(value)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment