hello guys, will show you a custom hook for handling async call.
useFetch
hook take a callback
as first argument and callback
params for rest arguments.
here it's:
const useFetch = (cb, ...params) => {
const isMounted = useRef();
const [response, setResponse] = useState();
const [loading, setLoading] = useState(false);
//const [error, setError] = useState();
return {
response,
loading,
isMounted,
reset: () => setResponse(),
fetch: async (reload = false) => {
try {
isMounted.current = true;
if (!response || reload) setLoading(true);
const data = await cb(...params);
if (isMounted.cuurent) {
if (data) setResponse(data)
}
} catch (error) {
errorNotification(error); // do something with the error
// or u can add setError(error)
}
finally{
setLoading(false);
}
}
};
};
Usage:
const UserProfile = ({ id }) => {
const { response, loading, fetch, isMounted } = useFetch(getUserProfile, id);
useEffect(() => {
fetch();
return () => {
isMounted.current = false;
};
}, []);
return (
<>{loading ? <p>Loading...</p> : response && <p>{response.userName}</p>}</>
);
};
Note: isMounted
is used to detect component unmount
for not firing unnecessary state update.
hope you like it,thanks.
Top comments (1)
Looks nice =)
I was looking for how other people are solving this same problem.
There is three changes I would make to that useFetch logic.
If you are interested, checkout the useFetch solution that I have been using github.com/jEnbuska/scratches/blob...