Skip to main content
Практика завдань

Підходи до управління станом у React

Управління станом у React

Вибір правильного підходу до управління станом залежить від того, який тип стану ви управляєте і наскільки широко він розподілений. React пропонує вбудовані варіанти, а екосистема надає потужні зовнішні бібліотеки.


Типи стану

ТипПрикладиНайкращий підхід
Локальний/UI станВведення форм, перемикачі, модальні вікнаuseState, useReducer
Спільний станТема, аутентифікація, кошикContext, Zustand, Redux
Серверний станДані API, кешTanStack Query, SWR
Стан URLФільтри, пагінаціяПараметри URL, параметри пошуку
Стан формиСкладна валідація формReact Hook Form, Formik

Вбудований: useState

tsx
function Counter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(c => c + 1)}>{count}</button>; }

Найкраще підходить для: Простого, локального стану компонента.

Вбудований: useReducer

tsx
type Action = { type: "increment" } | { type: "decrement" } | { type: "reset" }; function reducer(state: number, action: Action): number { switch (action.type) { case "increment": return state + 1; case "decrement": return state - 1; case "reset": return 0; } } function Counter() { const [count, dispatch] = useReducer(reducer, 0); return ( <div> <span>{count}</span> <button onClick={() => dispatch({ type: "increment" })}>+</button> <button onClick={() => dispatch({ type: "decrement" })}>-</button> </div> ); }

Найкраще підходить для: Складного локального стану з кількома діями.

Вбудований: Context API

tsx
const ThemeContext = createContext<"light" | "dark">("light"); function ThemeProvider({ children }: { children: React.ReactNode }) { const [theme, setTheme] = useState<"light" | "dark">("light"); return ( <ThemeContext.Provider value={theme}> {children} </ThemeContext.Provider> ); } function ThemedButton() { const theme = useContext(ThemeContext); return <button className={theme}>Click me</button>; }

Найкраще підходить для: Рідко змінюваних глобальних значень (тема, локаль, аутентифікація).

⚠️ Обмеження: всі споживачі повторно рендеряться, коли значення контексту змінюється.

Zustand (Легкий магазин)

tsx
import { create } from "zustand"; interface CartStore { items: Product[]; addItem: (item: Product) => void; removeItem: (id: string) => void; total: () => number; } const useCartStore = create<CartStore>((set, get) => ({ items: [], addItem: (item) => set(state => ({ items: [...state.items, item] })), removeItem: (id) => set(state => ({ items: state.items.filter(i => i.id !== id) })), total: () => get().items.reduce((sum, i) => sum + i.price, 0), })); // Використання — підписується лише на те, що читає function CartCount() { const count = useCartStore(state => state.items.length); return <span>{count}</span>; }

Найкраще підходить для: Простого до середнього спільного стану. Мінімальний шаблон, відмінна продуктивність.

Redux Toolkit

tsx
import { createSlice, configureStore } from "@reduxjs/toolkit"; const counterSlice = createSlice({ name: "counter", initialState: { value: 0 }, reducers: { increment: (state) => { state.value += 1 }, decrement: (state) => { state.value -= 1 }, }, }); const store = configureStore({ reducer: { counter: counterSlice.reducer } });

Найкраще підходить для: Великих додатків зі складним станом, проміжним програмним забезпеченням, інструментами розробника.

TanStack Query (Серверний стан)

tsx
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; function Users() { const { data, isLoading, error } = useQuery({ queryKey: ["users"], queryFn: () => fetch("/api/users").then(r => r.json()), }); if (isLoading) return <Spinner />; return <UserList users={data} />; }

Найкраще підходить для: Серверного стану — кешування, повторне отримання у фоновому режимі, оптимістичні оновлення, пагінація.

Посібник з прийняття рішень

Чи є це локальним для ОДНОГО компонента? → useState / useReducer Чи ділиться це ДЕЯКИМИ сусідніми компонентами? → Підняття стану вгору Чи є це глобальним, але змінюється РІДКО (тема, аутентифікація)? → Context API Чи є це глобальним і змінюється ЧАСТО? → Zustand (простий) або Redux Toolkit (складний) Чи є це даними з API? → TanStack Query / SWR

Важливо:

Немає єдиного найкращого рішення — використовуйте правильний інструмент для кожного типу стану. Почніть з useState, підніміть стан вгору, коли це необхідно, додайте Context для глобальних значень, використовуйте TanStack Query для даних сервера, і звертайтеся до Zustand або Redux лише коли це дійсно необхідно. Уникайте розміщення всього в глобальному стані.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Дочитали статтю?
Практика завдань