React Context API надає простий, але потужний спосіб керувати і ділитися станом в додатку без необхідності передавати пропси через кожен рівень дерева компонентів. У цій статті ми розглянемо, як побудувати повністю функціональний блог-додаток за допомогою React Context API.
Що таке Context API?
Context API в React — це можливість, яка дозволяє ділитися даними між компонентами без явного передавання пропсів через кожен рівень дерева компонентів. Це особливо корисно для керування глобальним станом, таким як налаштування теми, автентифікація користувача або будь-які спільні дані.
Структура Context API
- Створити Context: Використовуйте метод
createContext()
для ініціалізації контексту. - Надати Context: Використовуйте компонент
Context.Provider
для передавання стану та функцій вниз по дереву компонентів. - Використовувати Context: Використовуйте хук
useContext()
для доступу до значень контексту в дочірніх компонентах.
Огляд проекту
Цей блог-додаток складається з таких компонентів:
- Header: Відображає заголовок додатку.
- Blogs: Показує список блог-постів.
- Pagination: Дозволяє навігацію між сторінками блог-постів.
- Spinner: Відображає індикатор завантаження під час отримання даних.
Ми будемо використовувати Context API для керування станом блог-постів, пагінацією та статусом завантаження.
Налаштування проекту
Структура файлів
src/
|-- components/
| |-- Header.js
| |-- Blogs.js ==> const { posts, loading } = useContext(AppContext);
| |-- Pagination.js
| |-- Spinner.js
|-- context/
| |-- AppContext.js ==> const AppContext = createContext();
// {children} />
|-- App.js
|-- index.js
|-- baseUrl.js
baseUrl.js
export const baseUrl = "https://codehelp-apis.vercel.app/api/get-blogs";
Крок 1: Налаштування Context Provider
AppContext.js
import { createContext, useState } from "react";
import { baseUrl } from "../baseUrl";
// Крок 1: Створення Context
export const AppContext = createContext();
// Провайдер
export default function AppContextProvider({ children }) {
const [loading, setLoading] = useState(false);
const [posts, setPosts] = useState([]);
const [page, setPage] = useState(1);
const [totalPages, setTotalPages] = useState(null);
// Отримання блог-постів
// @param {number} page - Номер сторінки для отримання.
async function fetchBlogPosts(page = 1) {
setLoading(true);
let url = `${baseUrl}?page=${page}`;
try {
const result = await fetch(url);
const data = await result.json();
setPage(data.page);
setPosts(data.posts);
setTotalPages(data.totalPages);
} catch (error) {
console.log("Помилка при отриманні даних");
// скидаємо всі дані до початкових значень
setPage(1);
setPosts([]);
setTotalPages(null);
}
setLoading(false);
}
// Обробка зміни сторінки
function handlePageChange(page) {
setPage(page);
fetchBlogPosts(page);
}
// Значення Context / об'єкт необхідних даних
const value = {
loading,
setLoading,
posts,
setPosts,
page,
setPage,
totalPages,
setTotalPages,
fetchBlogPosts,
handlePageChange
};
// Крок 2: передача даних дочірнім компонентам
// {children} => передаємо значення "value={value}"
return
{children}
;
}
Крок 2: Ініціалізація додатку
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import AppContextProvider from "./context/AppContext";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
// children
);
Крок 3: Створення компонентів додатку
App.js
import React, { useContext, useEffect } from "react";
import Header from "./components/Header";
import Blogs from "./components/Blogs";
import Pagination from "./components/Pagination";
import { AppContext } from "./context/AppContext";
const App = () => {
const { fetchBlogPosts } = useContext(AppContext);
useEffect(() => {
fetchBlogPosts();
}, []);
return (
); }; export default App; ``` ## **Header.js** ``` import React from 'react'; const Header = () => { return (
Blogs
); }; export default Header; //************************************************** import React from 'react'; import './Header.css'; const Header = () => { return (
Blogs
); }; export default Header; ``` ## **Blogs.js** ``` import React, { useContext } from 'react'; import { AppContext } from '../context/AppContext'; /* map karte samay key pass jarur karo id ya phir index */ // Крок 3: використання даних const Blogs = () => { const { posts, loading } = useContext(AppContext); if (loading) { return
Завантаження...
; } if (posts.length === 0) { return
Блог-постів немає.
; } return ( // тепер мапимо всі пости і відображаємо кожен з них через компонент Card
{posts.map((post) => (
{post.title}
{post.content}
By {post.author}
))}
); }; export default Blogs; //************************************************** import React, { useContext } from 'react'; import { AppContext } from '../context/AppContext'; import './Blogs.css'; const Blogs = () => { const { posts, loading } = useContext(AppContext); return (
{loading ? (
Завантаження...
) : posts.length === 0 ? (
Блог-постів немає.
) : ( posts.map((post) => (
{post.title}
{post.content}
By {post.author}
)) )}
); }; export default Blogs; ``` ## Pagination.js ``` import React, { useContext } from 'react'; import { AppContext } from '../context/AppContext'; const Pagination = () => { const { page, totalPages, handlePageChange } = useContext(AppContext); return (
handlePageChange(page - 1)}> Попередня handlePageChange(page + 1)}> Наступна {`Сторінка ${page} з ${totalPages}`}
); }; export default Pagination; ``` ## Spinner.js ``` import React from 'react'; import './Spinner.css'; // Припускаємо, що тут містяться стилі для спіннера.
const Spinner = () => {
return (
); }; export default Spinner; ``` The React Context API є потужним інструментом для керування станом у вашому додатку, що усуває необхідність у прокиданні пропсів через всі рівні компонента. У цьому блозі ми продемонстрували, як ефективно використовувати Context API для керування глобальним станом, таким як отримання та відображення блог-постів, обробка пагінації та відображення стану завантаження. Ось основні висновки:
- **Спрощує керування станом**: Context API спрощує спільне використання та керування станом між компонентами в додатку React.
- **Перевикористовуваний та модульний код**: Завдяки таким компонентам, як `Header`, `Blogs`, `Pagination` та `Spinner`, структура додатку стає модульною і легшою для підтримки.
- **Гнучкість**: Ви можете легко розширити функціональність додатку, додаючи нові функції, такі як фільтрація або пошук блогів, без зміни основної структури.
- **Підвищення продуктивності розробника**: Використовуючи Context, ви можете зосередитись на створенні функціоналу, а не на складній логіці передачі стану.
Використовуючи Context API, ми створили легке та масштабоване рішення для нашого блогу. Для більших і складніших проектів ви можете доповнити Context API бібліотеками для керування станом, такими як Redux або Zustand, щоб додати додаткові функції та масштабованість.
Перекладено з: [Building a Blog Application with React “Context API” 😎](https://its-shivam07.medium.com/building-a-blog-application-with-react-context-api-8e1cfc11113b)