Пошук уроків, статей та іншого контенту
Навчитеся працювати з ресурсами, маршрутами, параметрами, заголовками та JSON-відповідями REST API.
REST API — це спосіб обміну даними між клієнтом і сервером через HTTP.
У React клієнтом є браузер, а REST API надає дані, наприклад:
список товарів;
інформацію про користувачів;
дописи;
замовлення.
Зазвичай сервер повертає дані у форматі JSON.
Приклад JSON-відповіді:
{
"id": 1,
"title": "Перший допис",
"completed": false
}React отримує цю відповідь, перетворює її на JavaScript-об’єкт і показує дані в інтерфейсі.
У REST API дані організовані як ресурси. Ресурсом може бути користувач, допис або товар.
Наприклад:
https://api.example.com/users
https://api.example.com/posts
https://api.example.com/productsЧастина після домену називається маршрутом або шляхом:
/users
/posts
/productsДля отримання конкретного ресурсу до маршруту додають його ідентифікатор:
/posts/10
/users/42Такий запит означає:
/posts — колекція дописів;
/posts/10 — допис з ідентифікатором 10.
| Метод | Призначення | |---|---| | GET | отримати дані | | POST | створити новий ресурс | | PUT | повністю оновити ресурс | | PATCH | частково оновити ресурс | | DELETE | видалити ресурс |
У React найчастіше починають із GET, щоб отримати дані для відображення.
fetchДля HTTP-запитів у браузері можна використовувати вбудовану функцію fetch.
fetch("https://api.example.com/posts")
.then((response) => response.json())
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error("Помилка запиту:", error);
});fetch повертає проміс. Спочатку потрібно отримати HTTP-відповідь, а потім перетворити її тіло з JSON:
const response = await fetch(url);
const data = await response.json();Важливо: fetch не вважає HTTP-помилки винятками автоматично. Наприклад, відповідь зі статусом 404 потрібно перевіряти самостійно за допомогою response.ok.
Для запиту після монтування компонента використовують useEffect.
Стан компонента зазвичай містить:
дані;
ознаку завантаження;
повідомлення про помилку.
import { useEffect, useState } from "react";
function Posts() {
const [posts, setPosts] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState("");
useEffect(() => {
async function loadPosts() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts?_limit=5",
{
headers: {
Accept: "application/json",
},
}
);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
const data = await response.json();
setPosts(data);
} catch (requestError) {
setError(requestError.message);
} finally {
setIsLoading(false);
}
}
loadPosts();
}, []);
if (isLoading) {
return <p>Завантаження...</p>;
}
if (error) {
return <p>Не вдалося завантажити дописи: {error}</p>;
}
return (
<section>
<h1>Дописи</h1>
<ul>
{posts.map((post) => (
<li key={post.id}>
<h2>{post.title}</h2>
<p>{post.body}</p>
</li>
))}
</ul>
</section>
);
}
export default Posts;У цьому прикладі:
useState([]) зберігає масив дописів.
useEffect запускає запит після появи компонента на сторінці.
fetch надсилає GET-запит.
?_limit=5 обмежує відповідь п’ятьма дописами.
response.json() перетворює JSON на JavaScript-значення.
setPosts(data) зберігає отримані дані.
map створює елемент списку для кожного допису.
Параметри запиту додають до URL після знака ?:
/posts?userId=3Якщо параметрів декілька, їх розділяють символом &:
/posts?userId=3&_limit=5У React URL із параметрами можна створювати за допомогою URLSearchParams:
import { useEffect, useState } from "react";
function UserPosts({ userId }) {
const [posts, setPosts] = useState([]);
useEffect(() => {
const params = new URLSearchParams({
userId: String(userId),
_limit: "5",
});
async function loadPosts() {
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?${params}`
);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
const data = await response.json();
setPosts(data);
}
loadPosts().catch((error) => {
console.error("Не вдалося завантажити дописи:", error);
});
}, [userId]);
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
export default UserPosts;Масив залежностей [userId] означає, що ефект виконається повторно, якщо значення userId зміниться.
Параметр шляху є частиною URL:
/posts/7Так можна отримати один конкретний ресурс:
const postId = 7;
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${postId}`
);
const post = await response.json();Не слід плутати параметри шляху з параметрами запиту:
/posts/7 // параметр шляху
/posts?id=7 // параметр запитуФормат залежить від API, тому потрібно використовувати той варіант, який визначив сервер.
Заголовки передають додаткову інформацію про запит.
Наприклад, заголовок Accept повідомляє серверу, який формат відповіді очікує клієнт:
const response = await fetch(
"https://api.example.com/posts",
{
headers: {
Accept: "application/json",
},
}
);Під час надсилання JSON на сервер потрібно вказати Content-Type:
const newPost = {
title: "Новий допис",
body: "Текст допису",
userId: 1,
};
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts",
{
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: JSON.stringify(newPost),
}
);
const createdPost = await response.json();
console.log(createdPost);Тут:
method: "POST" визначає тип операції;
Content-Type: "application/json" повідомляє, що тіло запиту містить JSON;
JSON.stringify(newPost) перетворює JavaScript-об’єкт на рядок JSON;
response.json() читає JSON-відповідь сервера.
Метод response.json() асинхронний, тому його потрібно очікувати за допомогою await:
const response = await fetch(url);
const data = await response.json();Після цього data може бути об’єктом:
console.log(data.title);Або масивом об’єктів:
data.map((item) => {
console.log(item.id);
});Форма відповіді залежить від API. Перед використанням даних варто перевірити документацію або подивитися відповідь у консолі браузера.
Сервер повертає статус, який описує результат запиту.
Поширені статуси:
200 OK — запит успішний;
201 Created — ресурс створено;
400 Bad Request — некоректні дані запиту;
401 Unauthorized — потрібна автентифікація;
404 Not Found — ресурс не знайдено;
500 Internal Server Error — помилка сервера.
Перевіряйте результат запиту перед читанням JSON:
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Запит завершився зі статусом ${response.status}`);
}
const data = await response.json();Під час отримання даних у React зазвичай виконують такі кроки:
Створюють стан для даних.
Створюють стан завантаження.
Створюють стан помилки.
У useEffect надсилають запит.
Перевіряють response.ok.
Читають JSON через response.json().
Зберігають дані у стані.
Відображають завантаження, помилку або результат.
Якщо не вказати другий аргумент useEffect, запит виконуватиметься після кожного рендерингу:
useEffect(() => {
// Запит
});Для запиту один раз після монтування використовуйте порожній масив залежностей:
useEffect(() => {
// Запит
}, []);response.okfetch може успішно завершити проміс навіть у випадку статусу 404 або 500.
Неправильно:
const response = await fetch(url);
const data = await response.json();Краще:
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
const data = await response.json();Об’єкт відповіді fetch не містить готові дані безпосередньо. Потрібно викликати:
const data = await response.json();Спочатку масив даних може бути порожнім. Інтерфейс має враховувати стан завантаження:
if (isLoading) {
return <p>Завантаження...</p>;
}keyПід час використання map кожен елемент списку повинен мати стабільний ключ:
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}REST API працює з ресурсами через HTTP-маршрути.
GET використовують для отримання даних, POST — для створення.
Конкретний ресурс можна вказати параметром шляху, наприклад /posts/7.
Параметри запиту додають після ?, наприклад ?userId=3.
Заголовки описують додаткові властивості запиту.
Для JSON у тілі запиту використовують Content-Type: application/json.
response.json() перетворює JSON-відповідь на JavaScript-дані.
У React запити зазвичай виконують у useEffect.
Стан компонента має враховувати дані, завантаження та помилки.
Перед обробкою відповіді потрібно перевіряти response.ok.