4
0
forked from crowetic/commerce

Updated useCart hook

This commit is contained in:
Luis Alvarez 2020-10-09 12:58:49 -05:00
parent 7758ea3199
commit 22ba0d7315
3 changed files with 54 additions and 23 deletions

View File

@ -1,21 +1,48 @@
import { HookFetcher, HookDeps } from '@lib/commerce/utils/types'
import { useCart as useCommerceCart } from '@lib/commerce/cart'
import type { Cart } from '../api/cart'
const defaultOpts = {
url: '/api/bigcommerce/cart',
}
export type { Cart }
export function useCart() {
const cart = useCommerceCart<Cart | null>()
// Uses a getter to only calculate the prop when required
// cart.data is also a getter and it's better to not trigger it early
Object.defineProperty(cart, 'isEmpty', {
get() {
return Object.values(cart.data?.line_items ?? {}).every(
(items) => !items.length
)
},
set: (x) => x,
export const fetcher: HookFetcher<Cart | null, HookDeps[]> = (
options,
_,
fetch
) => {
return fetch({
url: options?.url,
query: options?.query,
})
return cart
}
function extend(customFetcher: typeof fetcher) {
const useCart = () => {
const cart = useCommerceCart<Cart | null>(
[defaultOpts.url, undefined],
customFetcher
)
// Uses a getter to only calculate the prop when required
// cart.data is also a getter and it's better to not trigger it early
Object.defineProperty(cart, 'isEmpty', {
get() {
return Object.values(cart.data?.line_items ?? {}).every(
(items) => !items.length
)
},
set: (x) => x,
})
return cart
}
useCart.extend = extend
return useCart
}
export const useCart = extend(fetcher)

View File

@ -1,22 +1,24 @@
import useSWR, { responseInterface } from 'swr'
import Cookies from 'js-cookie'
import { HookDeps, HookFetcher } from '../utils/types'
import { useCommerce } from '..'
const CART_API = '/api/bigcommerce/cart'
export type CartResponse<C> = responseInterface<C, Error> & {
isEmpty: boolean
}
function useCart<C>() {
export function useCart<T>(
deps: [string | undefined, string | undefined, ...HookDeps[]],
fetcherFn: HookFetcher<T, HookDeps[]>
) {
const { fetcherRef, cartCookie } = useCommerce()
const fetcher = (url?: string, query?: string) =>
Cookies.get(cartCookie) ? fetcherRef.current({ url, query }) : null
const response = useSWR([CART_API, undefined], fetcher, {
const fetcher = (url?: string, query?: string, ...args: HookDeps[]) =>
Cookies.get(cartCookie)
? fetcherFn({ url, query }, args, fetcherRef.current)
: null
const response = useSWR(deps, fetcher, {
revalidateOnFocus: false,
})
return Object.assign(response, { isEmpty: true }) as CartResponse<C>
return Object.assign(response, { isEmpty: true }) as CartResponse<T>
}
export { useCart }

View File

@ -20,3 +20,5 @@ export type HookFetcherOptions = {
url?: string
method?: string
}
export type HookDeps = string | number | undefined[]