You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I really need a promise-based fetcher hook for my application. Otherwise, I would have to use a lot of nonlinear logic in useEffects. I just want to know if this will work as a replacement for Remix fetcher.
import { useMatches, useParams, useRevalidator } from '@remix-run/react'
import { useCallback, useState } from 'react'
import { $path, RouteId, Routes } from 'remix-routes'
import { Json } from 'types/database-generated.types'
type HookProps =
| {
routeId?: RouteId
} | undefined
type FetcherProps =
| {
method?: 'POST' | 'GET' | 'PUT' | 'DELETE' | 'PATCH'
body?: Json
} | undefined
export function usePromiseFetcher<T>({ routeId }: HookProps = {}) {
const [isPending, setIsPending] = useState(false)
const matches = useMatches()
const { revalidate } = useRevalidator()
const id = routeId ? routeId : (matches.at(-1)?.id as RouteId | undefined)
if (!id) throw new Error(`Somehow, there is no route ID: ${routeId}`)
const urlWithParams = id
.replace('routes', '')
.replace('_index', '')
.replace('root', '')
.replaceAll('.', '/')
.replaceAll('$', ':') as keyof Routes
const params = useParams()
const apiUrl = $path(urlWithParams, params)
if (!id) throw new Error(`No route matches ${routeId}`)
const fetcher = useCallback(
async ({ body, method = 'GET' }: FetcherProps = {}) => {
setIsPending(true)
const url = `${apiUrl}?_data=${id}`
const res = await fetch(url, {
method,
body: JSON.stringify(body),
headers: {
'Content-Type': 'application/json',
},
})
const data = res.json() as SerializeFrom<T>
setIsPending(false)
if (method != 'GET') revalidate()
if (res.ok) return data
throw new Error(res.statusText)
},
[apiUrl, id, revalidate],
)
return {
isPending,
fetcher,
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I really need a promise-based fetcher hook for my application. Otherwise, I would have to use a lot of nonlinear logic in useEffects. I just want to know if this will work as a replacement for Remix fetcher.
Beta Was this translation helpful? Give feedback.
All reactions