Skip to content

Instantly share code, notes, and snippets.

@dandelionadia
Last active March 19, 2020 15:04
Show Gist options
  • Save dandelionadia/98b81d6ee5dbb14f7be683a39532f797 to your computer and use it in GitHub Desktop.
Save dandelionadia/98b81d6ee5dbb14f7be683a39532f797 to your computer and use it in GitHub Desktop.
Building React Hook + TypeScript
export interface ProductData {
id: string
title: string
description: string
rating: number
price: number
images: string[]
relatedProducts: string[]
shopAttributes: ProductAttributes[]
reviews: ProductReview[]
}
export interface ProductAttributes {
title: string
data: number | string
}
export interface ProductReview {
name: string
date: string
rating: number
text: string
}
const ProductPage: React.FC<RouteComponentProps<{
productId: string
}>> = ({ match }) => {
//match => it is Route word wich not about 'id' in the 'path'
const { productId } = match.params
// { loading, data } = useQuery === useQuery.loading, useQuery.data (get state in the useQuery for using it here when: if(!data)... )
// useQuery<ProductData> === useQuery is using interface <ProductData>
//useQuery<ProductData>(`/product/${productId}`) === called function with data
const { loading, data } = useQuery<ProductData>(`/product/${productId}`)
if (loading) {
return <p>Product is loading...</p>
}
if (!data) {
return <p>Error when fetching product</p>
}
return (
<>
<Box padding={1.3} paddingMd={2.6} marginHorizontalLgDown={2}>
<ProductSummary
customerReviews={3}
title={data.title}
rating={data.rating}
price={data.price}
description={data.description}
/>
</Box>
</>
)
}
export { ProductPage }
import { useState, useEffect } from 'react'
interface UseQueryReturn<DataType> {
loading: boolean
data: DataType | null
}
//const useQuery = <DataType = any> === useQuery will get any interface insted of <DataType> (my word that will change)
//useQuery = <DataType = any>(url: string) === (url) we will get any data insted of url wich going to the fetch link
//: UseQueryReturn<DataType> === it is tyo wich we give to the uaeQuery when it will be called (useQuery(foo))
//UseQueryReturn<DataType> === we will get any interfase insted of <DataType> (my word that will change) ; in my situation in is <DataType> === <T> q
export const useQuery = <DataType = any>(
url: string
): UseQueryReturn<DataType> => {
//state by default
const [state, setState] = useState<UseQueryReturn<DataType>>({
data: null,
loading: false
})
useEffect(() => {
//changes state
setState({ loading: true, data: null })
fetch(`https://auros-api.netlify.com/.netlify/functions/api${url}`)
.then(res => res.json())
//when we will gt data => chanching state
.then(res => setState({ data: res, loading: false }))
///when it is not data => change state
.catch(() => setState({ data: null, loading: false }))
}, [url])
return state
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment