Skip to content

Instantly share code, notes, and snippets.

@naoki-sawada
Last active May 24, 2021 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naoki-sawada/c842f7484ebf31cb9d0232266f6f9a7d to your computer and use it in GitHub Desktop.
Save naoki-sawada/c842f7484ebf31cb9d0232266f6f9a7d to your computer and use it in GitHub Desktop.
React hook and fetch example code.
import React, { useCallback, useEffect, useState } from "react";
import axios, { AxiosRequestConfig } from "axios";
class FetchError extends Error {
constructor({ name, message }: { name: string, message: string }) {
super(message);
this.name = name;
}
}
function useFetch<T>(url: string, config: AxiosRequestConfig) {
const [data, setData] = useState<T>();
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<FetchError>();
const fetch = useCallback(async () => {
axios(url, config)
.then((res) => setData(res.data))
.catch(e => {
if (e.response.data?.error) {
return setError(new FetchError({ ...e.response.data.error }));
}
return setError(e);
})
.finally(() => setLoading(false));
}, [url, config]);
const refetch = useCallback(() => {
setLoading(true);
fetch();
}, [fetch]);
useEffect(() => {
fetch();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return { data, loading, error, refetch };
}
type User = {
name: string;
}
function App() {
const { data, loading, error, refetch } = useFetch<User>("http://localhost:3000/name", {
method: "get",
params: { name: "bbb" },
});
if (loading) return <div>loading...</div>;
if (error) return <div style={{color: "red"}}>{error.message}</div>;
return (
<div>
<div>{data?.name}</div>
<button onClick={refetch}>Reload</button>
</div>
);
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment