Использование контроллера прерывания в его исходном виде:
const controller = new AbortController();
const { signal } = controller;
...
fetch(url, { signal });
...
// abort
controller.abort();
Чтобы прервать эффект fetch
в полете
useEffect(() => {
const controller = new AbortController();
const { signal } = controller;
fetch(url, { signal });
return () => {
controller.abort(); // abort on unmount for cleanup
};
}, []);
I нашел статью очень информативной, когда мне нужно было разработать способ отмены запросов на выборку.
Редактировать
Необходимо добавить signal
к fetch
объекту параметров запросов. Вы также можете определить функцию async fetchData
внутри эффекта (это нормально), так что все это включено в область обратного вызова ловушки эффекта.
export const useMovieDetailsFetch = (movieId) => {
const [state, setState] = useState({})
const [loading, setLoading] = useState(true)
const [error, setError] = useState(false)
useEffect(() => {
const controller = new AbortController();
const { signal } = controller;
const fetchData = async () => {
setError(false);
setLoading(true);
try {
const movieDetailsEndpoint = `${MOVIE_API_URL}movie/${movieId}?api_key=${MOVIE_KEY}`;
const result = await (
await fetch(movieDetailsEndpoint, { signal })
).json();
const creditsEndpoint = `${MOVIE_API_URL}movie/${movieId}/credits?api_key=${MOVIE_KEY}`;
const creditsResult = await (
await fetch(creditsEndpoint, { signal })
).json();
// Filtring in crew for directors only
const movieDirectors = creditsResult.crew.filter(
(member) => member.job === 'Director'
);
setState({
...result,
movieDirectors,
actors: creditsResult.cast,
});
} catch (error) {
setError(true);
}
setLoading(false);
}
fetchData();
return () => controller.abort();
}, [movieId]);
return [state, loading, error];
}