Skip to content

Instantly share code, notes, and snippets.

@simicd
Created September 27, 2020 17:35
Show Gist options
  • Save simicd/d7ad5c0cdaee4a931378a52b2a731626 to your computer and use it in GitHub Desktop.
Save simicd/d7ad5c0cdaee4a931378a52b2a731626 to your computer and use it in GitHub Desktop.
import { useState, useEffect, useCallback } from "react";
export const useFetch = ({ url, init, processData }) => {
// Response state
const [data, setData] = useState();
// Turn objects into strings for useCallback & useEffect dependencies
const [stringifiedUrl, stringifiedInit] = [JSON.stringify(url), JSON.stringify(init)];
// If no processing function is passed just cast the object to type T
// The callback hook ensures that the function is only created once
// and hence the effect hook below doesn't start an infinite loop
const processJson = useCallback(processData || ((jsonBody) => jsonBody), []);
// Define asynchronous function
const fetchApi = async () => {
try {
// Fetch data from REST API
const response = await fetch(url, init);
if (response.status === 200) {
// Extract json
const rawData = await response.json();
const processedData = processJson(rawData);
setData(processedData);
} else {
console.error(`Error ${response.status} ${response.statusText}`);
}
} catch (error) {
console.error(`Error ${error}`);
}
};
useEffect(() => {
// Call async function
fetchApi();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [stringifiedUrl, stringifiedInit, processJson]);
return { data, fetchApi };
};
// DogImageWithButton.tsx
import React from "react";
import { useFetch } from "./useFetch";
export const DogImageWithButton = () => {
/** Fetch image on button click */
const { data, fetchApi } = useFetch({
url: "https://dog.ceo/api/breed/beagle/images/random",
});
const getImage = () => {
fetchApi();
};
return (
<>
{data ? <img src={data.message} alt="dog"></img> : <div>Loading</div>}
<button onClick={() => getImage()}>New Image</button>
</>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment