From 8fc85e415f249b5c2782cc3b88e48be2597376fb Mon Sep 17 00:00:00 2001 From: dm1sh Date: Tue, 11 Jul 2023 14:43:08 +0300 Subject: [PATCH] Added component unmount cleanup --- front/src/hooks/api/useAddAnnouncement.js | 31 ++++++++++++++++++++--- front/src/hooks/api/useBook.js | 2 +- front/src/hooks/api/useFetch.js | 23 ++++++++++++++--- front/src/utils/index.js | 6 +++-- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/front/src/hooks/api/useAddAnnouncement.js b/front/src/hooks/api/useAddAnnouncement.js index 8217ead..0b7f9d4 100644 --- a/front/src/hooks/api/useAddAnnouncement.js +++ b/front/src/hooks/api/useAddAnnouncement.js @@ -1,15 +1,30 @@ -import { useState } from "react" +import { useEffect, useRef, useState } from "react" import { API_URL } from "../../config" const useAddAnnouncement = () => { const [status, setStatus] = useState("Опубликовать") + const timerIdRef = useRef() + const abortControllerRef = useRef() + const doAdd = async (formData) => { - setStatus(true) + if (status === "Загрузка") { + abortControllerRef.current?.abort() + setStatus("Отменено") + timerIdRef.current = setTimeout(() => setStatus("Опубликовать"), 3000) + return + } + + setStatus("Загрузка") + + const abortController = new AbortController() + abortControllerRef.current = abortController + try { const res = await fetch(API_URL + "/announcement", { method: 'PUT', body: formData, + signal: abortController.signal }) const data = await res.json() @@ -21,9 +36,17 @@ const useAddAnnouncement = () => { } catch (err) { setStatus(err.message ?? err) - setTimeout(() => setStatus("Опубликовать"), 10000) + timerIdRef.current = setTimeout(() => setStatus("Опубликовать"), 10000) } - } + } + + useEffect(() => { + const abortController = abortControllerRef.current + return () => { + clearTimeout(timerIdRef.current) + abortController?.abort() + } + }) return {doAdd, status} } diff --git a/front/src/hooks/api/useBook.js b/front/src/hooks/api/useBook.js index e7dc9e5..37c38df 100644 --- a/front/src/hooks/api/useBook.js +++ b/front/src/hooks/api/useBook.js @@ -10,7 +10,7 @@ function useBook(id) { const [status, setStatus] = useState('') const handleBook = () => { - const token = getToken() || "Test" + const token = getToken() if (token) { setStatus("Загрузка") diff --git a/front/src/hooks/api/useFetch.js b/front/src/hooks/api/useFetch.js index a6c67e5..ab1997e 100644 --- a/front/src/hooks/api/useFetch.js +++ b/front/src/hooks/api/useFetch.js @@ -1,12 +1,22 @@ -import { useEffect, useState } from "react" +import { useEffect, useRef, useState } from "react" +import { isAborted } from '../../utils' const useFetch = (url, params, initialData) => { const [data, setData] = useState(initialData) const [loading, setLoading] = useState(true) const [error, setError] = useState("") + const abortControllerRef = useRef(null) + useEffect(() => { - fetch(url, params) + if (abortControllerRef.current) { + abortControllerRef.current.abort() + } + + const abortController = new AbortController() + abortControllerRef.current = abortController + + fetch(url, { ...params, signal: abortControllerRef.current.signal }) .then(res => { if (!res.ok) { switch (res.status) { @@ -27,16 +37,21 @@ const useFetch = (url, params, initialData) => { setLoading(false) }) .catch(err => { - setError("Ошибка сети") + if (!isAborted(err)) { + setError("Ошибка сети") + } + setLoading(false) if (import.meta.env.DEV) { console.log(url, params, err) } }) + + return () => abortControllerRef.current.abort() }, [url, params]) - return { data, loading, error } + return { data, loading, error, abort: abortControllerRef.current?.abort } } export default useFetch diff --git a/front/src/utils/index.js b/front/src/utils/index.js index a5f048e..f24284b 100644 --- a/front/src/utils/index.js +++ b/front/src/utils/index.js @@ -5,6 +5,8 @@ const removeNull = (obj) => Object.fromEntries( key, value === Object(value) ? removeNull(value) : value, ]), -); +) -export { removeNull } \ No newline at end of file +const isAborted = (err) => err.name == 'AbortError' + +export { removeNull, isAborted } \ No newline at end of file