В React-компонентах легко управлять локальным состоянием с помощью useState или useReducer. Но что, если нам нужно делиться состоянием между несколькими компонентами, часто находящимися в разных частях дерева? Вот здесь начинается настоящий вызов, который решается с помощью управления глобальным состоянием.
Сегодня мы разберём, зачем нужен Redux, его основные принципы, а также познакомимся с современными альтернативами. На практике создадим минимальное приложение для управления списком покупок с помощью Redux Toolkit.
Зачем нужен Redux?
Redux — это библиотека для управления состоянием приложения. Она помогает хранить глобальные данные, которые могут использоваться несколькими компонентами, и предоставляет удобные инструменты для работы с ними.
Проблемы, которые решает Redux:
- Пропс-дриллинг: Передача данных через несколько уровней компонентов.
- Сложность синхронизации состояния: Когда одно и то же состояние изменяется из разных частей приложения.
- Трудности с отладкой: Redux делает изменения состояния прозрачными и предсказуемыми.
Основные принципы Redux:
- Единый источник правды: Всё состояние приложения хранится в одном объекте — store.
- Только для чтения: Состояние нельзя изменить напрямую. Единственный способ — отправить действие (action), описывающее изменение.
- Чистые функции: Логика изменения состояния определяется редьюсерами — функциями, которые принимают текущее состояние и действие, а возвращают новое состояние.
Современные альтернативы Redux
Redux долгое время был стандартом для управления глобальным состоянием, но с развитием React появились более лёгкие и удобные решения. Вот некоторые из них:
Zustand
Минималистичная библиотека для управления состоянием.
Простая и понятная API: состояние создаётся через функции, без редьюсеров и экшенов.
Идеально для небольших и средних приложений.
Пример
import create from 'zustand';
const useStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}));
Jotai
Библиотека атомарного состояния. Каждая часть состояния хранится в атоме, который можно подключать к компонентам.
Прямой доступ к состоянию, без промежуточных слоёв.
Пример
import { atom, useAtom } from 'jotai';
const countAtom = atom(0);
function Counter() {
const [count, setCount] = useAtom(countAtom);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
React Query
Решение для работы с данными из API. Управляет кэшированием, синхронизацией и состоянием загрузки данных.
Лучше всего подходит для управления серверным состоянием.
Пример
import { useQuery } from 'react-query';
function Users() {
const { data, isLoading } = useQuery('users', fetchUsers);
if (isLoading) return <p>Загрузка...</p>;
return <ul>{data.map((user) => <li key={user.id}>{user.name}</li>)}</ul>;
}
Почему всё ещё стоит изучать Redux?
- Мощность и гибкость: Подходит для сложных приложений.
- Прозрачность: Легко отследить, что изменило состояние, благодаря экшенам и редьюсерам.
- Экосистема: Большое сообщество, плагины и поддержка.
С Redux Toolkit настройка и использование Redux стали проще, устранив многие недостатки оригинального Redux.
Практика: список покупок с Redux Toolkit
Создадим приложение, где пользователь может:
- Добавлять товары в список покупок.
- Удалять товары из списка.
- Просматривать текущий список.
Шаг 1: Установка Redux Toolkit
Убедитесь, что Redux Toolkit установлен:
npm install @reduxjs/toolkit react-redux
Шаг 2: Настройка Redux
Создаём файл store.js для хранения состояния:
import { configureStore, createSlice } from '@reduxjs/toolkit';
// Создаём slice (редьюсер и экшены)
const shoppingListSlice = createSlice({
name: 'shoppingList',
initialState: [],
reducers: {
addItem: (state, action) => {
state.push(action.payload);
},
removeItem: (state, action) => {
return state.filter((item, index) => index !== action.payload);
},
},
});
export const { addItem, removeItem } = shoppingListSlice.actions;
const store = configureStore({
reducer: {
shoppingList: shoppingListSlice.reducer,
},
});
export default store;
Шаг 3: Подключение Redux к React
Оборачиваем приложение в Provider:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
Шаг 4: Компоненты приложения
Создаём компонент для списка покупок:
Компонент списка:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { removeItem } from './store';
function ShoppingList() {
const items = useSelector((state) => state.shoppingList);
const dispatch = useDispatch();
return (
<ul>
{items.map((item, index) => (
<li key={index}>
{item}{' '}
<button onClick={() => dispatch(removeItem(index))}>
Удалить
</button>
</li>
))}
</ul>
);
}
export default ShoppingList;
Компонент добавления:
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { addItem } from './store';
function AddItem() {
const [text, setText] = useState('');
const dispatch = useDispatch();
const handleSubmit = (e) => {
e.preventDefault();
if (text.trim()) {
dispatch(addItem(text));
setText('');
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Добавьте товар"
/>
<button type="submit">Добавить</button>
</form>
);
}
export default AddItem;
Шаг 5: Объединяем компоненты
В App.jsx подключаем все компоненты:
import React from 'react';
import ShoppingList from './ShoppingList';
import AddItem from './AddItem';
function App() {
return (
<div style={{ padding: '20px', fontFamily: 'Arial, sans-serif' }}>
<h1>Список покупок</h1>
<AddItem />
<ShoppingList />
</div>
);
}
export default App;
Шаг 6: Запускаем проект
Запустите приложение:
npm start
Добавляйте товары, удаляйте их, и ваш список будет обновляться в реальном времени.
Итоги
Сегодня мы разобрали:
- Зачем нужен Redux: Для управления глобальным состоянием в сложных приложениях.
- Современные альтернативы: Zustand, Jotai, React Query — для разных сценариев.
- На практике создали приложение с Redux Toolkit.
Redux или альтернативы?
- Выберите Redux для сложных приложений.
- Рассмотрите Zustand или Jotai для лёгких и средних задач.
- Используйте React Query для работы с серверными данными.
Теперь вы можете уверенно выбирать инструменты для управления состоянием в ваших проектах.
Комментарии
0