Jak się obsługuje globalnie błędy z axiosa w Reakcie? Chciałbym, żeby po otrzymaniu np. 500
przekierować użytkownika automatycznie do jakiejś strony z błędem, podobnie w przypadku 401
i 404
. Jak na razie napisałem jakieś bazowe fetch
, w którym robię try/catch
i przekierowuję korzystając z globalnego obiektu history
. Tak się to obecnie robi czy może jakoś nowocześnie przy użyciu Context API i hooków? I czy może w ogóle lepiej wyświetlić jakieś powiadomienie w przypadku błędu zamiast przekierowywać do innej strony?
Może hook useEffect, a w nim w function(error) robisz switcha i w zależności od kodu błędu robisz przekierowanie? Przekierowanie w przypadku kodu błędu jest częstą praktyką i jest ok.
@Haskell Znalazłem taką bibliotekę: https://github.com/tannerlinsley/react-query. Tu oni sugerują, żeby robić if/else
przy renderowaniu komponentu.
function Todos() {
const { data, isLoading, error } = useQuery('todos', fetchTodoList)
return (
<div>
{isLoading ? (
<span>Loading...</span>
) : error ? (
<span>Error: {error.message}</span>
) : data ? (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
) : null}
</div>
)
}
Myślałem też o napisaniu jakiegoś hooka useFetch
, takiego jak tu: https://blog.blackbox-vision.tech/fetch-data-using-react-hooks
Zobacz sobie jak działają "Interceptors": https://www.npmjs.com/package/axios#interceptors
W callbacku odpalanym w przypadku błędu zrób sobie switcha na error.response.status
(kody http odpowiedzi) i tam zrób sobie przekierowania gdzie chcesz. Pamiętaj tylko, że jeżeli nie wywołasz tam żadnego przekierowania i jednocześnie callback ten nie zwróci Promise.reject to kod wyżej nie wyłapie tego w catchu.
Na podstawie tego, co robi się na backendzie, napisałem sobie jakieś bazowe callAPI
, w którym przechwytuję te wyjątki i zwracam jakiś Result
.
const result = await fetchSomething(...)
if (result.success) setData(result.data)
else setError(result.error)
setIsLoading(false)
@alkyms Automatyczne przekierowywanie wydaje się być bardzo wygodne, tylko trochę dziwnie to wygląda, jak wywołanie funkcji odpytującej API przekierowuje na inną stronę. Sam już nie wiem.
Hmmm... jeśli masz taką potrzebę aby zrobić jakieś przekierowanie w momencie gdy API zwróci Ci np. 402 to nie widzę w tym nic dziwnego.
Zerknij może na ten filmik. Nie oglądałem go do końca ale gość tutaj chce chyba właśnie coś podobnego sklecić co może CI się przydać:
Fajne, tylko że on robi mniej więcej coś podobnego do tego, co napisałem w drugim poście. Tylko że używa do tego useReducer
(myślałem, że useReducer
używa się, jak się ma, nie wiem, 10 useState'ów, a nie 4 - jak to z tym jest?).
W sumie taka opcja z try/catch
+ interceptor wydaje się być chyba najlepsza. Te błędy, które wiemy jak obsłużyć niezależnie od komponentu, obsługujemy w interceptorze, a komponent obsługuje pozostałe.
useReducer jest alternatywą dla useState natomiast ja postrzegam to tak, że należy go używać nie jako zamiennika lecz w sytuacjach gdy nasz nowy stan ma być zależny od poprzedniego. try/catch
+ interceptor może się udać, jednak będzie miało jedną wadę. Za każdym razem w komponencie będziesz musiał jakoś definiować wychwytywanie i reagowanie na błędy niezdefiniowane wcześniej. W dużej aplikacji gdzie będzie sporo odwołań do API będziesz notorycznie łamał zasadę DRY bo przecież jeśli jakieś błędy będą występowały to będą powtarzalne i powinny być wykrywane przynajmniej poziom wyżej niż komponent z którego wychodzi request.
No właśnie. Jak żyć?
Ten problem zostanie rozwiązany, jak Suspense
będzie gotowe. :) https://pl.reactjs.org/docs/concurrent-mode-suspense.html#handling-errors
With Suspense, handling fetching errors works the same way as handling rendering errors — you can render an error boundary anywhere to “catch” errors in components below.
React to jednak przyszłość.
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.