Jak pobierać dane z API w Reakcie za pomocą hooków?

React

readTime

8 min

Jak pobierać dane z API w Reakcie za pomocą hooków?

Custom hook z użyciem useState() i useEffect()

Aby pobierać dane z jakiegokolwiek API za pomocą wbudowanych hooków Reacta, można wprowadzić custom hook - useFetch, który wewnętrznie wykorzystuje useState i useEffect

useFetch.js

_21
_21
import { useState, useEffect } from 'react'
_21
_21
const useFetch = url => {
_21
const [state, setState] = useState([null, false]);
_21
_21
useEffect(() => {
_21
setState([null, true]);
_21
_21
(async () => {
_21
const data = await fetch(url)
_21
.then(res => res.json());
_21
_21
setState([data.body, false]);
_21
})();
_21
}, [url]);
_21
_21
return state;
_21
};
_21
_21
export default useFetch;

Ta funkcja zwraca tablicę z dwiema zmiennymi: zawartością stanu i flagą ładowania.

Domyślnie, w linii:4, widać, że zaczynamy od wartości null i false. Nic się nie ładuje.

Ale potem ustawiamy ładowanie na true w linii:8 i wewnątrz anonimowej funkcji asynchronicznej pobieramy dane.

Gdy dane zostaną zwrócone, aktualizujemy stan za pomocą funckji setState, do której jako pierszy element w tablicy przekazujemy wartość stanu i drugi element ustawiamy na false ponieważ pobieranie danych z API zostało zakończone.

Należy pamiętać, że nie można bezpośrednio wywołać asynchronicznego callbacka w useEffect. Dlatego należy zdefiniować w nim oddzielną funkcję asynchroniczną.

Skorzystałem tutaj z IIFE, czyli Immediately-invoked function expression. Jak sama nazwa mówi jest to natychmiastowo samowywołująca się funkcja. Czyli funkcja, która wykonuje się od razu.

Robimy tak gdy chcemy natychmiast wywołać funkcję i nie ma potrzeby jej definiowania a następnie wywoływania.

Możesz przekazać adres url do tablicy zależności useEffect. Dla Reacta oznacza to, aby ponownie wywołał hook useEffect() tylko wtedy, gdy zmieni się adres URL.

Aby użyć tego hooka, możesz wprowadzić go do swojego komponentu w następujący sposób:


_10
// Po zaimportowaniu hooka useFetch
_10
const Post = () => {
_10
const [post, loading] = useFetch('https://jsonplaceholder.typicode.com/posts/1');
_10
_10
if (loading) {
_10
return <Loading />
_10
}
_10
_10
return <PostBody content={post} />;
_10
};

Jak radzić sobie z obsługą błędów w przypadku pobierania danych z API?

Tradycyjnym sposobem uzyskania danych lub informacji o błędzie z Promisa jest użycie then i catch.


_33
import React, { useState, useEffect } from 'react'
_33
_33
function FetchAPI() {
_33
_33
const [users, setUsers] = useState([])
_33
const [isError, setIsError] = useState(false);
_33
_33
useEffect(() => {
_33
fetch('https://jsonplaceholder.typicode.com/users').then((response) => {
_33
if (response.ok) {
_33
return response.json();
_33
} else {
_33
throw 'Error getting users list'
_33
}
_33
}).then((data) => {
_33
setUsers(data);
_33
}).catch((error) => {
_33
setIsError(true)
_33
})
_33
}, [])
_33
_33
return (
_33
<div>
_33
{isError ? <h3> Error! Please try again later</h3> :
_33
<ul>
_33
{users.map((user) => <li key={user.id} > {user.name} </li>)}
_33
</ul>
_33
}
_33
</div>
_33
)
_33
}
_33
_33
export default FetchAPI

Zauważ, jak zwróciliśmy dane lub komunikat o błędzie, w oparciu o odpowiedź w pierwszej funkcji wywołania zwrotnego then. Ważną rzeczą, na którą należy zwrócić uwagę w przypadku fetch API, jest to, że jeśli wystąpi błąd, taki jak 404, funkcja wywołania zwrotnego then zostanie wykonana, a funkcja wywołania zwrotnego wewnątrz catch nie zostanie wykonana. Tak więc, w oparciu o odpowiedź z serwera, musimy albo pobrać dane z odpowiedzi, albo rzucić komunikat o błędzie, który trafia do bloku catch.

W powyższym przykładzie sprawdziliśmy właściwość ok odpowiedzi. Zamiast tego można sprawdzić status odpowiedzi (na przykład 200, 404 lub 500 itp.) i podjąć odpowiednie działania.

Jak używać Fetch API async - await z try - catch w hooku useEffect w aplikacji React?

Innym powszechnie stosowanym sposobem z fetch API jest użycie async i await. Aby obsłużyć błędy, możemy użyć opcji try-catch w naszej aplikacji.


_39
_39
import React, { useState, useEffect } from 'react'
_39
_39
function FetchAPI() {
_39
_39
const [users, setUsers] = useState([])
_39
const [isError, setIsError] = useState(false);
_39
_39
useEffect(() => {
_39
_39
const fetchData = async () => {
_39
try {
_39
let response = await fetch('https://jsonplaceholder.typicode.com/users');
_39
if (response.status === 200) {
_39
let data = await response.json();
_39
setUsers(data);
_39
} else {
_39
throw 'Error fetching users list'
_39
}
_39
} catch (error) {
_39
setIsError(true)
_39
}
_39
}
_39
fetchData();
_39
_39
}, [])
_39
_39
return (
_39
<div>
_39
{isError ? <h3> Error! Please try again later</h3> :
_39
<ul>
_39
{users.map((user) => <li key={user.id} > {user.name} </li>)}
_39
</ul>
_39
}
_39
</div>
_39
)
_39
}
_39
_39
export default FetchAPI

W powyższym przykładzie sprawdziliśmy kod statusu odpowiedzi zamiast właściwości ok, jak to zrobiliśmy w pierwszym przykładzie. Tutaj sprawdziliśmy tylko status 200. W aplikacjach tzw. real-time może być konieczne sprawdzenie również kilku innych kodów statusu, takich jak 201, 404 lub 500 itp.

źródło: https://howtojs.io/how-to-use-fetch-api-with-async-await-try-catch-then-catch-in-useeffect-hook-in-react-application/

authorImg

Witek Pruchnicki

Z pasją dzielę się wiedzą o programowaniu i nie tylko na różne sposoby

Spis treści