Handling Fetch Requests
This example demonstrates the correct way to handle fetch requests in React using the useEffect hook and the AbortController API. When making API calls within useEffect, it's important to clean up ongoing requests to prevent issues such as unnecessary network traffic, potential data conflicts, and memory leaks.
Key Points:
AbortController This API allows you to cancel ongoing fetch requests. By creating an instance of AbortController and passing its signal to the fetch request, you can cancel the request when the component unmounts or when the dependencies change.
Signal Property The signal property of AbortController is used to link the fetch request with the controller, enabling the cancellation of the request when necessary.
Cleanup Function The cleanup function inside useEffect (return () => { controller.abort(); }) ensures that any ongoing fetch request is canceled when the component unmounts or when the id changes, avoiding memory leaks and potential errors.
This approach helps to keep your application performant and reliable, especially when dealing with frequent state changes or component unmounting. Additionally, libraries like SWR or React Query can provide a more streamlined approach for data fetching and caching in React applications.
import { useEffect, useState } from "react";
const Twelve = () => {
// Fetching in useEffect
const [id, setId] = useState(1);
return (
<div>
<button
onClick={() => setId(Math.floor(Math.random() * 100))}
className="bg-blue-500 px-4 py-2 text-white rounded mr-2"
>
Show me a different post
</button>
<Post id={id} />
</div>
);
};
export function Post({ id }) {
const [text, setText] = useState("");
useEffect(() => {
// why fetching should be done here
const controller = new AbortController();
fetch(`https://dummyjson.com/posts/${id}`, {
signal: controller.signal,
})
.then((res) => res.json())
.then((data) => setText(data.body));
return () => {
controller.abort(); // changing the id now won't interrupt our execution - cleanup occurs each time before the new request
};
}, [id]); // should update on each button click - [id] instead of []
return <p>{text}</p>;
}
export default Twelve;
/*
AbortController and Its Usage:
AbortController is a built-in browser API that allows you to cancel asynchronous operations like fetch requests.
It is useful when you need to ensure that a request is canceled if the component unmounts or if the input data changes before the request completes.
Unnecessary Requests: If the input data changes frequently, many unnecessary requests could be made.
controller.signal:
The signal property of the AbortController object is passed to the fetch request to control and cancel the request if needed.
Why is this necessary?
Canceling requests when id changes:
If the user changes the id several times, you want to cancel the current request to avoid unnecessary requests and potential data conflicts.
Preventing memory leaks:
If the component unmounts before the request completes, you want to cancel the request to free up resources and prevent attempts to update the state of an unmounted component.
https://swr.vercel.app/
Fetching data without directly using fetch
*/