2021-05-11 14:37:15 +00:00
|
|
|
import { useCallback, useState } from "react"
|
2021-04-26 20:08:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook which fetches data from the backend on the first render of a component.
|
|
|
|
*
|
|
|
|
* @param fetchData - The function to use when fetching data.
|
|
|
|
* @param method - The HTTP method to use.
|
|
|
|
* @param path - The HTTP path to fetch the data at.
|
|
|
|
* @param body - The body of the HTTP request (it will be JSONified before being sent).
|
|
|
|
* @param init - Additional `init` parameters to pass to `fetch`.
|
|
|
|
*/
|
|
|
|
export default function useData(fetchData, method, path, body, init) {
|
|
|
|
const [error, setError] = useState(null)
|
|
|
|
const [data, setData] = useState(null)
|
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load data from the API.
|
|
|
|
*/
|
|
|
|
const load = useCallback(
|
|
|
|
async () => {
|
2021-05-10 12:13:12 +00:00
|
|
|
console.debug(`Loading ${method} ${path}...`)
|
2021-04-26 20:08:52 +00:00
|
|
|
setLoading(true)
|
|
|
|
|
2021-05-10 12:13:12 +00:00
|
|
|
console.debug(`Fetching ${method} ${path}...`)
|
2021-04-26 20:08:52 +00:00
|
|
|
try {
|
|
|
|
const _data = await fetchData(method, path, body, init)
|
2021-05-10 12:13:12 +00:00
|
|
|
console.debug(`Displaying data of ${method} ${path}: `, _data)
|
2021-04-26 20:08:52 +00:00
|
|
|
setData(_data)
|
2021-05-11 14:37:15 +00:00
|
|
|
}
|
|
|
|
catch(e) {
|
2021-05-10 12:13:12 +00:00
|
|
|
console.debug(`Displaying error of ${method} ${path}: `, e)
|
2021-04-26 20:08:52 +00:00
|
|
|
setError(e)
|
2021-05-11 14:37:15 +00:00
|
|
|
}
|
|
|
|
finally {
|
2021-05-10 12:13:12 +00:00
|
|
|
console.debug(`Stopping loading of ${method} ${path}...`)
|
2021-04-26 20:08:52 +00:00
|
|
|
setLoading(false)
|
|
|
|
}
|
|
|
|
},
|
2021-05-11 14:37:15 +00:00
|
|
|
[fetchData, method, path, body, init],
|
2021-04-26 20:08:52 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Invalidate the data loaded from the API and try to load it again.
|
|
|
|
*/
|
2021-05-07 23:40:49 +00:00
|
|
|
const fetchNow = useCallback(
|
2021-04-26 20:08:52 +00:00
|
|
|
async () => {
|
|
|
|
console.debug("Clearing data...")
|
|
|
|
setData(null)
|
|
|
|
|
|
|
|
console.debug("Clearing error...")
|
|
|
|
setError(null)
|
|
|
|
|
|
|
|
await load()
|
|
|
|
},
|
2021-05-11 14:37:15 +00:00
|
|
|
[load],
|
2021-04-26 20:08:52 +00:00
|
|
|
)
|
|
|
|
|
2021-05-11 14:37:15 +00:00
|
|
|
return { data, error, loading, fetchNow }
|
2021-04-26 20:08:52 +00:00
|
|
|
}
|