4
0
forked from crowetic/commerce
commerce/lib/commerce/index.tsx
2020-10-22 18:05:56 -05:00

52 lines
1.2 KiB
TypeScript

import {
ReactNode,
MutableRefObject,
createContext,
useContext,
useMemo,
useRef,
} from 'react'
import { Fetcher } from './utils/types'
const Commerce = createContext<CommerceContextValue | {}>({})
export type CommerceProps = {
children?: ReactNode
config: CommerceConfig
}
export type CommerceConfig = { fetcher: Fetcher<any> } & Omit<
CommerceContextValue,
'fetcherRef'
>
export type CommerceContextValue = {
fetcherRef: MutableRefObject<Fetcher<any>>
locale: string
cartCookie: string
}
export function CommerceProvider({ children, config }: CommerceProps) {
if (!config) {
throw new Error('CommerceProvider requires a valid config object')
}
const fetcherRef = useRef(config.fetcher)
// Because the config is an object, if the parent re-renders this provider
// will re-render every consumer unless we memoize the config
const cfg = useMemo(
() => ({
fetcherRef,
locale: config.locale,
cartCookie: config.cartCookie,
}),
[config.locale, config.cartCookie]
)
return <Commerce.Provider value={cfg}>{children}</Commerce.Provider>
}
export function useCommerce<T extends CommerceContextValue>() {
return useContext(Commerce) as T
}