Skip to content

Instantly share code, notes, and snippets.

@chaoticbit
Created November 6, 2020 07:19
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 chaoticbit/be3923fb976ab452ba43cddec4ffe5f7 to your computer and use it in GitHub Desktop.
Save chaoticbit/be3923fb976ab452ba43cddec4ffe5f7 to your computer and use it in GitHub Desktop.
React Hooks
import { useEffect, useRef, useReducer } from 'react';
export const useFetch = (url) => {
const cache = useRef({});
const initialState = {
status: 'idle',
error: null,
data: [],
};
const [state, dispatch] = useReducer((state, action) => {
switch (action.type) {
case 'FETCHING':
return { ...initialState, status: 'fetching' };
case 'FETCHED':
return { ...initialState, status: 'fetched', data: action.payload };
case 'FETCH_ERROR':
return { ...initialState, status: 'error', error: action.payload };
default:
return state;
}
}, initialState);
useEffect(() => {
let cancelRequest = false;
if (!url)
return;
const fetchData = async () => {
dispatch({ type: 'FETCHING' });
if (cache.current[url]) {
const data = cache.current[url];
dispatch({ type: 'FETCHED', payload: data });
} else {
try {
const response = await fetch(url);
const data = await response.json();
cache.current[url] = data;
if (cancelRequest) return;
dispatch({ type: 'FETCHED', payload: data });
} catch (error) {
if (cancelRequest) return;
dispatch({ type: 'FETCH_ERROR', payload: error.message });
}
}
};
fetchData();
return function cleanup() {
cancelRequest = true;
}
}, [url]);
return state;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment