JavaRush /Курсы /Модуль 3: React /Установка Redux и Redux Toolkit — настройка проекта для и...

Установка Redux и Redux Toolkit — настройка проекта для использования Redux

Модуль 3: React
6 уровень , 1 лекция
Открыта

Что такое Redux Toolkit?

Перед вами самая лаконичная, компактная и современная библиотека на базе Redux! Redux Toolkit (RTK) – это официальный инструмент Redux, который значительно упрощает процесс разработки, минимизируя схватку с "боевыми роботами" (нет, не с багами, те проще!).

RTK создали, чтобы избавить разработчиков от излишне сложной конфигурации традиционного Redux (где нужно было вручную подключать кучу разных модулей, определять действия, редьюсеры и прочее). Здесь вы получите "всё включено" в одном пакете: настройку хранилища, работу с асинхронными экшенами и даже инструменты для иммутабельности.

Преимущества Redux Toolkit:

  • Меньше кода: вы сокращаете количество шаблонного кода.
  • Асинхронная работа: интегрированный инструмент createAsyncThunk для работы с API.
  • Типизация: RTK идеально подходит для TypeScript, делая ваш код безопасным.
  • Иммутабельность: библиотека immer встроена прямо в Toolkit, позволяя вам менять состояние "как будто напрямую", но без нарушений правил Redux.

А теперь — поехали устанавливать и настраивать!

1. Установка необходимых пакетов

Мы начнём с установки RTK и реактовской библиотеки для работы с Redux. Как говорится, "никакой магии, только npm и немного терпения".

npm install @reduxjs/toolkit react-redux

Если вы работаете с Yarn (потому что вам нравится стиль команд в одном слове):

yarn add @reduxjs/toolkit react-redux

Что мы установили:

  • @reduxjs/toolkit: это сама библиотека Redux Toolkit.
  • react-redux: официальная библиотека для интеграции Redux с React, позволяющая повесить глобальное хранилище на наше приложение и использовать хуки вроде useSelector и useDispatch.

2. Настройка проекта: создаём Redux Store

Redux Store — это сердце Redux-приложения. Здесь мы будем хранить всё его состояние. Настроим его с помощью метода configureStore, который входит в Redux Toolkit.

Почему configureStore лучше, чем ручная настройка? Он автоматически подключает несколько полезных инструментов, таких как DevTools для отладки и встроенная защита от мутаций состояния. Никакой боли с настройкой middlewares!

Создаём файл для Store

Для начала создайте папку redux в корне проекта. Внутри создайте файл store.ts.

// redux/store.ts
import { configureStore } from '@reduxjs/toolkit';

export const store = configureStore({
  reducer: {}, // Пока тут пусто, позже добавим редьюсеры
});

// Типизируем RootState и AppDispatch для TypeScript
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Обратите внимание:

  1. Мы пока передали пустой объект в reducer — сюда позже подключаются наши срезы (slices), которые будут управлять различными частями состояния.
  2. Мы определили типы RootState и AppDispatch. Это нужно, чтобы позже типизировать работу с хуками useSelector и useDispatch.

3. Оборачиваем <App /> в <Provider>

Чтобы React-компоненты могли получать доступ к Redux Store, нам нужно внедрить компонент <Provider> из библиотеки react-redux. Он позволяет передать Store через контекст, чтобы компоненты могли его использовать.

Откройте файл src/index.tsx или src/main.tsx (в зависимости от вашего проекта) и добавьте код:

// index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { store } from './redux/store'; // Подключаем наш Store
import App from './App';

ReactDOM.render(
  <Provider store={store}> {/* Передаём Store в Provider */}
    <App />
  </Provider>,
  document.getElementById('root')
);

Теперь наше приложение обёрнуто в <Provider>, а значит, любой компонент внутри <App /> сможет использовать Redux Store. Вам даже не нужно передавать данные через пропсы (да-да, время прощаться с "пропс-дриллингом").

4. Добавляем первый Slice

Redux Toolkit предлагает концепцию "срезов" (slice). Slice — это логическая часть состояния (например, данные о пользователе, список задач), а также набор методов для управления этим состоянием.

Создайте файл redux/slices/counterSlice.ts:

// redux/slices/counterSlice.ts
import { createSlice } from '@reduxjs/toolkit';

// Определяем интерфейс для состояния
interface CounterState {
  value: number;
}

// Устанавливаем начальное состояние
const initialState: CounterState = {
  value: 0,
};

// Создаём Slice
const counterSlice = createSlice({
  name: 'counter', // Имя среза
  initialState,
  reducers: {
    increment(state) {
      state.value += 1; // Immer позволяет нам "казаться" будто мы мутируем состояние
    },
    decrement(state) {
      state.value -= 1;
    },
    addByAmount(state, action) {
      state.value += action.payload;
    },
  },
});

// Экспортируем экшены и редьюсер
export const { increment, decrement, addByAmount } = counterSlice.actions;
export default counterSlice.reducer;

Что здесь происходит:

  1. createSlice: это метод, который создаёт срез. Он генерирует действия (increment, decrement, addByAmount) и редьюсер.
  2. Immer: позволяет нам использовать мутационный синтаксис при работе с состоянием, сохраняя его неизменяемость под капотом. Подробнее через несколько лекций.
  3. Типизация: мы описали интерфейс CounterState, чтобы TypeScript понял, что состояние должно быть числом.

5. Подключаем Slice к Store

Чтобы Store "узнал" о нашем новом срезе, мы должны добавить его в configureStore.

Откройте redux/store.ts и подключите counterSlice:

// redux/store.ts
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './slices/counterSlice'; // Импортируем редьюсер

export const store = configureStore({
  reducer: {
    counter: counterReducer, // Добавляем Slice в Store
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

Теперь наш Slice встроен в глобальный Store. Данные из него будут доступны через путь state.counter.

6. Подключаем Slice к компоненту

Создайте базовый компонент Counter.tsx, который будет взаимодействовать с нашим срезом.

// components/Counter.tsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootState } from '../redux/store'; // Импортируем RootState для типизации
import { increment, decrement, addByAmount } from '../redux/slices/counterSlice';

const Counter = () => {
  const dispatch = useDispatch();
  const counter = useSelector((state: RootState) => state.counter.value);

  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button onClick={() => dispatch(increment())}>+1</button>
      <button onClick={() => dispatch(decrement())}>-1</button>
      <button onClick={() => dispatch(addByAmount(5))}>+5</button>
    </div>
  );
};

export default Counter;

В этом примере:

  1. useSelector извлекает значение из Store.
  2. useDispatch отправляет экшены в Store.
  3. Мы типизировали state в useSelector с помощью RootState.

Теперь ваш проект готов к работе с Redux Toolkit, и вы можете наслаждаться управлением состоянием без лишней боли. Хотите добавить ещё один Slice? Легко! Теперь это дело пары минут.

1
Задача
Модуль 3: React, 6 уровень, 1 лекция
Недоступна
Установка зависимостей
Установка зависимостей
1
Задача
Модуль 3: React, 6 уровень, 1 лекция
Недоступна
Создание и настройка Redux Store
Создание и настройка Redux Store
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ