Skip to content

Commit 0dea219

Browse files
committed
Add useApi hook
1 parent e4a362f commit 0dea219

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

packages/next-drupal/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './useAntdBreakpoints'
2+
export * from './useApi'
23
export * from './useAppState'
34
export * from './useContentItems'
45
export * from './useDebouncedValue'
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// @todo: add typescript types
2+
import {
3+
DependencyList,
4+
useCallback,
5+
useEffect,
6+
useMemo,
7+
useState,
8+
} from 'react'
9+
10+
const defaultHeaders: { [key: string]: { [key: string]: any } } = {
11+
common: {
12+
Accept: 'application/json',
13+
},
14+
del: {},
15+
patch: {
16+
'Content-Type': 'application/json',
17+
},
18+
post: {
19+
'Content-Type': 'application/json',
20+
},
21+
put: {
22+
'Content-Type': 'application/json',
23+
},
24+
get: {},
25+
}
26+
27+
export function useApi(
28+
path: string,
29+
opts?: { manualTrigger?: boolean } & RequestInit,
30+
deps?: DependencyList,
31+
) {
32+
const [state, setState] = useState<any>({
33+
data: null,
34+
error: null,
35+
loaded: false,
36+
loading: false,
37+
})
38+
39+
const getData = useCallback(
40+
async (opts?: RequestInit) => {
41+
setState((state) => ({ ...state, loaded: false, loading: true }))
42+
43+
const method = opts?.method || 'GET'
44+
let result: any = null
45+
46+
const response = await fetch(path, {
47+
...(opts || {}),
48+
headers: {
49+
...defaultHeaders.common,
50+
...defaultHeaders[method.toLowerCase()],
51+
...(opts?.headers || {}),
52+
},
53+
})
54+
55+
try {
56+
result = await response.json()
57+
} catch (error) {
58+
result = {
59+
message: response.statusText,
60+
}
61+
}
62+
63+
if (!response.ok) {
64+
setState((state) => ({
65+
...state,
66+
data: null,
67+
error: result,
68+
loaded: false,
69+
loading: false,
70+
}))
71+
return
72+
}
73+
74+
setState((state) => ({
75+
...state,
76+
data: result,
77+
error: null,
78+
loaded: true,
79+
loading: false,
80+
}))
81+
},
82+
[path],
83+
)
84+
85+
const value = useMemo(() => ({ ...state, getData }), [state, getData])
86+
87+
useEffect(() => {
88+
if (opts?.manualTrigger) return
89+
getData(opts)
90+
}, [getData, opts, deps])
91+
92+
return value
93+
}

0 commit comments

Comments
 (0)