Skip to content

Commit

Permalink
Add useApi hook
Browse files Browse the repository at this point in the history
  • Loading branch information
razvanMiu committed May 21, 2024
1 parent e4a362f commit 0dea219
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/next-drupal/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './useAntdBreakpoints'
export * from './useApi'
export * from './useAppState'
export * from './useContentItems'
export * from './useDebouncedValue'
Expand Down
93 changes: 93 additions & 0 deletions packages/next-drupal/src/hooks/useApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// @todo: add typescript types
import {
DependencyList,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'

const defaultHeaders: { [key: string]: { [key: string]: any } } = {
common: {
Accept: 'application/json',
},
del: {},
patch: {
'Content-Type': 'application/json',
},
post: {
'Content-Type': 'application/json',
},
put: {
'Content-Type': 'application/json',
},
get: {},

Check failure on line 24 in packages/next-drupal/src/hooks/useApi.ts

View workflow job for this annotation

GitHub Actions / Linting

Expected "get" to come before "put"
}

export function useApi(
path: string,
opts?: { manualTrigger?: boolean } & RequestInit,
deps?: DependencyList,
) {
const [state, setState] = useState<any>({
data: null,
error: null,
loaded: false,
loading: false,
})

const getData = useCallback(
async (opts?: RequestInit) => {
setState((state) => ({ ...state, loaded: false, loading: true }))

const method = opts?.method || 'GET'
let result: any = null

const response = await fetch(path, {
...(opts || {}),
headers: {
...defaultHeaders.common,
...defaultHeaders[method.toLowerCase()],
...(opts?.headers || {}),
},
})

try {
result = await response.json()
} catch (error) {
result = {
message: response.statusText,
}
}

if (!response.ok) {
setState((state) => ({
...state,
data: null,
error: result,
loaded: false,
loading: false,
}))
return
}

setState((state) => ({
...state,
data: result,
error: null,
loaded: true,
loading: false,
}))
},
[path],
)

const value = useMemo(() => ({ ...state, getData }), [state, getData])

useEffect(() => {
if (opts?.manualTrigger) return
getData(opts)
}, [getData, opts, deps])

return value
}

0 comments on commit 0dea219

Please sign in to comment.