Skip to content

Instantly share code, notes, and snippets.

@nico-martin
Last active August 8, 2022 18:21
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nico-martin/24de5872c5afc641df5f73c3ae6ee762 to your computer and use it in GitHub Desktop.
Save nico-martin/24de5872c5afc641df5f73c3ae6ee762 to your computer and use it in GitHub Desktop.
useApi.jsx - the correct way to fetch data with react hooks: extension of https://dev.to/nicomartin/the-right-way-to-fetch-data-with-react-hooks-48gc
// ./PostList.jsx
import React from 'react';
import {apiStates, useApi} from './useApi.jsx'
const PostList = () => {
const { state, error, data, reload } = useApi('https://api.mysite.com');
switch (state) {
case apiStates.ERROR:
return (
<React.Fragment>
<p>ERROR: {error || 'General error'}</p>
<button onClick={() => reload()}>retry</button>
</React.Fragment>
case apiStates.SUCCESS:
return (
<React.Fragment>
<p>Data:</p>
<ul>
{data.map((element) => (
<li>{element.title}</li>
))}
</ul>
</React.Fragment>
);
default:
return <p>loading..</p>;
}
};
// ./useApi.jsx
import React from 'react';
export const apiStates = {
LOADING: 'LOADING',
SUCCESS: 'SUCCESS',
ERROR: 'ERROR',
};
export const useApi = url => {
const [data, setData] = React.useState({
state: apiStates.LOADING,
error: '',
data: [],
});
const setPartData = (partialData) => setData({ ...data, ...partialData });
const load = () => {
setPartData({
state: apiStates.LOADING,
});
fetch(url)
.then((response) => response.json())
.then((data) => {
setPartData({
state: apiStates.SUCCESS,
data
});
})
.catch(() => {
setPartData({
state: apiStates.ERROR,
error: 'fetch failed'
});
});
};
React.useEffect(() => {
load();
}, []);
return [...data, reload: load];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment