Flowme: https://github.com/jewelislam360

Что такое Редукс?

Как говорится на официальном сайте Redux, это «контейнер с предсказуемым состоянием для приложений JS».

Это позволяет нам централизовать поток данных в единый контейнер, называемый хранилищем, с которым мы можем взаимодействовать с помощью действий.

Действия — это команды, которые мы делегируем нашим редукторам для получения содержащихся данных или манипулирования ими.

Редукторы — это записи хранилища. В магазине может быть один или несколько редукторов, обычно разделенных по функциям.

Представьте, что у нас может быть список задач, составляющих редюсер. Редюсер может воздействовать на определенные операции CRUD в соответствии с его инструкциями после того, как в этом отношении было делегировано определенное действие.

Допустим, для нашего репозитория могут быть определены следующие действия:

  • getAllTodos, который извлекает все сохраненные задачи редуктора
  • createTodo, который содержит информацию, необходимую для создания новой задачи.
  • updateTodo, который включает идентификатор задачи, которую мы хотим обновить, а также ее новые данные.
  • removeTodo, который состоит из идентификатора задачи, которую мы хотим удалить.

При работе с Redux нам приходится делегировать действия по внесению изменений в состояние хранилища, поскольку оно доступно только для чтения.

Это означает, что мы переписываем фактическое состояние редуктора каждый раз, когда вносим изменения.

Поток данных Redux

Поток данных в Redux выглядит примерно так:

Настройка Redux

Теперь, когда мы получили лучшее представление о том, что такое Redux, давайте посмотрим, как мы можем добавить его в наше приложение React.

Создайте новый проект React

Давайте начнем с создания совершенно нового проекта React. Мы можем сделать это с помощью команды терминала CRA:

  • НПМ: npm init react-app app-name
  • npx: npx create-react-app app-name
  • пряжа: yarn create react-app app-name

Это даст нам новый проект React.

Установите зависимости Redux

Современный способ добавления Redux в наше приложение React потребует от нас установки нового набора инструментов Redux Toolkit, а также пакета утилит react-redux, которые мы можем добавить через выбранный нами менеджер пакетов:

  • НПМ: npm install @reduxjs/toolkit react-redux
  • пряжа: yarn add @reduxjs/toolkit react-redux

Это должно предоставить нам все необходимые утилиты для настройки нашего хранилища, а также получения и установки данных.

Конфигурация хранилища Redux

На этом этапе нам нужно будет создать новый файл store/index.js в каталоге src/ для хранения конфигурации хранилища Redux:

import { configureStore } from '@reduxjs/toolkit';
const store = configureStore({});
export default store;

Пока оставим параметр функции configureStore пустым. Туда нам нужно будет добавить редукторы, которые мы определим на более позднем этапе.

Теперь мы хотим ссылаться на хранилище глобально, чтобы иметь возможность получить к нему доступ из любой точки нашего приложения.

Мы сделаем это в нашем файле src/index.js следующим образом:

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import "./index.css";
import App from "./App";
import store from "./store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <Provider store={store}>
    <App />
  </Provider>
);

Настройка редуктора

Настроив хранилище, мы можем приступить к настройке нашего редуктора; в этой статье мы рассмотрим редуктор для приложения todos.

Редюсер будет определен в новом каталоге reducers/ внутри уже существующего каталога store/ и будет содержать JS-файл с именем функции, в нашем случае «todos»:

const initialState = [];
const todosReducer = (state = initialState, action) => {
  switch (action.type) {
    case "GET_TODOS":
      return state;
case "ADD_TODO":
      return [...state, action.payload.todo];
case "UPDATE_TODO":
      return state.map((todo) => {
        if (todo.id === action.payload.todoId) {
          return {
            ...todo,
            ...action.payload.data,
          };
        }
return todo;
      });
case "REMOVE_TODO":
      return state.filter((todo) => todo.id !== action.payload.todoId);
default:
      return state;
  }
};
export default todosReducer;

Все редукторы Redux ожидают двух основных аргументов:

  • Состояние редуктора
  • Входящее действие

Всякий раз, когда мы отправляем команду, она будет передана в качестве параметра вызову редуктора; именно поэтому у нас также есть свойство «type» для каждого действия, поскольку оно позволяет нам различать каждую команду, полученную в редукторе.

Нам также нужно теперь ссылаться на этот редуктор в конфигурации хранилища, чтобы Redux знал о нем:

import { configureStore } from "@reduxjs/toolkit";
import todosReducer from "./reducers/todos";
const store = configureStore({
  reducer: {
    todos: todosReducer,
  },
});
export default store;

todos — это ключевое слово, которое мы будем использовать при получении данных задач, то есть имя свойства для редуктора todosReducer внутри конфигурации хранилища.

Настройка действий

Как упоминалось в начале статьи, у нас будет 4 действия CRUD, которые мы определим в новом файле todos.js в новом каталоге actions/ в уже существующем каталоге store/.

Этот файл будет содержать все наши определения действий. На действия не будут ссылаться в хранилище, а скорее вызывать их в нашем приложении всякий раз, когда они нам могут понадобиться.

Код действий будет выглядеть примерно так:

export const getTodos = () => ({
  type: "GET_TODOS",
});
export const addTodo = (data) => ({
  type: "ADD_TODO",
  payload: {
    todo: data,
  },
});
export const updateTodo = (todoId, data) => ({
  type: "UPDATE_TODO",
  payload: {
    todoId: todoId,
    data,
  },
});
export const removeTodo = (todoId) => ({
  type: "REMOVE_TODO",
  payload: {
    todoId,
  },
});

В этом нет ничего особенного; у нас есть свойство type внутри объекта, который мы будем возвращать для каждого действия, чтобы наш редуктор мог различать различные действия, а также любые дополнительные данные через свойство payload.