В этой статье я объясню, что такое Redux и как его использовать с React, на примере создания простого приложения Counter.

Введение

A. Обзор Redux

Redux — популярная библиотека управления состоянием для приложений JavaScript, особенно для React. Он предоставляет централизованное хранилище для управления состоянием приложения и упрощает понимание и отладку изменений состояния в вашем приложении.

B. Цель использования Redux с React

React — отличная библиотека для создания компонентов пользовательского интерфейса, но она не предоставляет встроенного способа управления состоянием приложения. Вот где на помощь приходит Redux. Используя Redux, вы можете централизовать состояние своего приложения и поддерживать его синхронизацию с компонентами пользовательского интерфейса. Это упрощает понимание и отладку вашего приложения, а также повышает производительность.

II. Понимание магазина Redux

A. Управление состоянием в React

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

B. Что такое магазин Redux

Redux Store — это объект, который хранит состояние приложения и делает его доступным для всех компонентов. Хранилище содержит дерево состояний и разрешает доступ через селекторы и отправленные действия. Хранилище является единственным источником достоверной информации и обеспечивает предсказуемые обновления состояния.

C. Понимание действий и редукторов

Действия Redux — это объекты, которые представляют намерение изменить состояние. Они отправляются в хранилище Redux для запуска обновления состояния. Действия содержат информацию о предполагаемом изменении, такую ​​как тип изменения и любые соответствующие данные.

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

Короче говоря, действия описывают изменения, а редукторы реализуют эти изменения в состоянии.

D. Понимание Redux-Toolkit

Redux-Toolkit — это набор утилит для Redux, которые упрощают настройку и управление магазином Redux. Он предоставляет более простой и эффективный способ управления состоянием вашего приложения, упрощая создание сложных приложений с помощью Redux и React.

Redux-Toolkit использует концепцию слайсов.

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

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

В Redux-Toolkit слайсы создаются с помощью функции createSlice. Эта функция принимает объект начального состояния и набор редукторов и возвращает объект среза, который можно комбинировать с другими слайсами для создания полного решения по управлению состоянием для вашего приложения.

III. Создание приложения React-Redux

А. Настройка проекта

Я рекомендую начать с создания простых React-приложений с помощью create-react-app. Создадим новый проект:

npx create-react-app counter-app
cd counter-app

Следующий шаг — установка всех необходимых зависимостей. В нашем случае это Redux, React-Redux и Redux Toolkit:

npm install redux react-redux @reduxjs/toolkit

Теперь у нас есть все необходимые зависимости.

Б. Настройка магазина

Прежде всего вам нужно создать новый каталог для хранения всего, что связано с магазином. Давайте создадим каталог store с index.js файлом под src:

src/
|-- store/
| |-- index.js
|-- App.js
|-- index.js

Создать магазин Redux с помощью Redux Toolkit можно быстро и просто. Вы можете использовать функцию configureStore для настройки хранилища с разумными значениями по умолчанию и легко добавлять промежуточное ПО и усилители по мере необходимости.

configureStore возвращает экземпляр хранилища, который мы затем экспортируем для использования в нашем приложении. Экземпляр хранилища имеет стандартные методы Redux, такие как getState, dispatch и subscribe, а также другие полезные методы, предоставляемые Redux Toolkit.

источник/магазин/index.js

import { configureStore } from "@reduxjs/toolkit";

const store = configureStore({
  reducer: {}
});

export default store;

Следующим шагом является предоставление хранилища всему приложению. Вы можете сделать это, используя компонент Provider из библиотеки React-Redux.

источник/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { Provider } from "react-redux";
import store from "./store";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
      <Provider store={store}>
          <App />
      </Provider>
  </React.StrictMode>
);

Теперь каждый компонент в приложении имеет доступ к созданному хранилищу.

C. Создание действий и редюсеров (Slice)

Одной из ключевых особенностей Redux Toolkit является функция createSlice, которая позволяет вам определять редьюсер и связанные с ним действия в одном месте. Эта функция генерирует создателей действий и типы действий для вас, а также может обрабатывать создание переходника для вас.

Давайте создадим counterSlice:

источник/магазин/counterSlice.js

import { createSlice } from "@reduxjs/toolkit"; const counterSlice = createSlice({ name: "counter", iimport { createSlice } from "@reduxjs/toolkit";

const counterSlice = createSlice({
  name: "counter",
  initialState: {
    value: 0
  },
  reducers: {
    increment: state => {
      state.value += 1;
    },
    decrement: state => {
      state.value -= 1;
    }
  }
});

export default counterSlice.reducer;

export const { increment, decrement } = counterSlice.actions;

В этом примере createSlice используется для создания нового среза для счетчика с начальным значением 0. Свойство reducers определяет два действия, increment и decrement, которые используются для обновления состояния.

Действия используются для отправки данных из вашего приложения в магазин Redux. В Redux-Toolkit действия определяются как функции в вашем фрагменте. Например:

const { increment, decrement } = counterSlice.actions;

Редюсеры используются для обновления состояния в хранилище Redux на основе полученных действий. В Redux-Toolkit свойство reducers среза используется для определения того, как должно обновляться состояние.

Следующий шаг — обновление хранилища только что созданным фрагментом.

источник/магазин/index.js

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./counterSlice";

const rootReducer = combineReducers({
  counter: counterReducer
});

const store = configureStore({
  reducer: rootReducer
});

export default store;

Функция combineReducers — это служебная функция в Redux, которая позволяет объединять несколько редьюсеров в один корневой редьюсер. Корневой редьюсер — это функция, которая передается функции createStore для создания хранилища Redux.
Каждый редьюсер в функции combineReducers отвечает за управление определенным фрагментом состояния. Функция combineReducers принимает объект, в котором каждое свойство сопоставляется с функцией-редуктором, а ключ каждого свойства используется для определения соответствующего среза состояния.
Например, если у вас есть счетчик и профиль пользователя в вашем состояние, вы можете использовать combineReducers следующим образом:

const rootReducer = combineReducers({
  counter: counterReducer,
  profile: profileReducer,
});

const store = configureStore({ 
  reducer: rootReducer
});

В этом примере counterReducer отвечает за управление частью состояния counter, а profileReducer отвечает за управление частью состояния profile. Эти два редуктора объединяются в rootReducer с помощью функции combineReducers.

Теперь у вас есть все, чтобы начать использовать это состояние внутри приложения.

D. Доступ к хранилищу из компонентов

Давайте создадим компонент, который будет использовать хранилище.

Библиотека react-redux предоставляет набор хуков, которые упрощают подключение компонентов к хранилищу Redux и отправке действий.

Самый важный хук — это хук useSelector, который позволяет вам извлекать состояние из хранилища и сопоставлять его с реквизитами компонента.

Источник/Компоненты/Counter.js

import React from 'react';
import { useSelector } from "react-redux";

const Counter = () => {
 const counterValue = useSelector(state => state.counter.value);

 return (
  <div>{counterValue}</div>
 );
};

export default Counter;

Компонент Counter использует хук useSelector для извлечения значения счетчика из хранилища и отображения его на странице.

Другой важный хук — хук useDispatch, который позволяет вам получить доступ к функции dispatch из действий сохранения и отправки.

Источник/Компоненты/Counter.js

import React from 'react';
import { useDispatch, useSelector } from "react-redux";
import { increment, decrement } from "../store/counterSlice";

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

 return (
  <div>
   <button onClick={() => dispatch(decrement())}>-</button>
   {counterValue}
   <button onClick={() => dispatch(increment())}>+</button>
  </div>
 );
};

export default Counter;

Компонент Counter теперь использует хук useDispatch для доступа к функции dispatch из хранилища и отправки действий для увеличения и уменьшения значения хранилища с помощью кнопок.

источник/App.js

import './App.css';
import Counter from "./components/Counter";

function App() {
  return (
    <div className="App">
      <Counter />
    </div>
  );
}

export default App;

Теперь приложение-счетчик готово, и вы можете попробовать его!

IV. Лучшие практики использования Redux

При использовании Redux с React важно, чтобы магазин был простым. Наличие большого и сложного хранилища может затруднить понимание того, что происходит, и усложнить отладку проблем. Чтобы сохранить магазин простым, примите во внимание следующие советы:

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

V. Заключение

A. Резюме преимуществ использования Redux

Redux дает несколько преимуществ при использовании в сочетании с React:

  1. Централизованное управление состоянием: Redux предоставляет централизованное хранилище для состояния вашего приложения, что упрощает управление и отслеживание изменений вашего состояния с течением времени.
  2. Предсказуемые обновления состояния: Redux следует строгим правилам обновления состояния, что упрощает понимание и прогнозирование того, как состояние вашего приложения будет меняться с течением времени.
  3. Повторно используемая логика состояния: Redux поощряет вас писать модульную и многократно используемую логику состояния, что упрощает управление и поддержку вашего приложения по мере его роста.
  4. Улучшенная производительность: Redux обеспечивает эффективные обновления состояния вашего приложения, уменьшая количество ненужных повторных рендеров в ваших компонентах React.
  5. Простая отладка: Redux предоставляет подробный журнал всех изменений состояния, что упрощает отладку и понимание того, как меняется состояние вашего приложения.
  6. Улучшенная структура кода: Redux помогает писать более чистый и структурированный код, поощряя вас писать модульную, повторно используемую и хорошо организованную логику управления состоянием.
  7. Улучшенная совместная работа: Redux упрощает совместную работу нескольких разработчиков над проектом, поскольку предоставляет четкий и четко определенный способ управления состоянием в приложении React.

B. Недостатки использования Redux

Хотя использование Redux с React имеет несколько преимуществ, следует учитывать и некоторые потенциальные недостатки:

  1. Крутая кривая обучения: Redux может быть сложным и трудным для изучения, особенно для разработчиков, которые плохо знакомы с концепцией управления состоянием.
  2. Накладные расходы: использование Redux может привести к дополнительным накладным расходам и сложности вашего приложения, особенно если вы управляете большим и сложным состоянием.
  3. Шаблонный код: Redux требует значительного объема шаблонного кода, который может быть повторяющимся и отнимать много времени на написание.
  4. Проблемы с производительностью: в некоторых случаях использование Redux может негативно повлиять на производительность вашего приложения, особенно если вы не будете осторожны с тем, как вы управляете обновлениями состояния.
  5. Сложности тестирования. Тестирование кода, использующего Redux, может быть сложнее, чем тестирование обычных компонентов React, поскольку вам нужно тестировать как обновления состояния, так и компоненты, которые полагаются на это состояние.
  6. Подробный код: Redux часто требует написания более подробного и сложного кода по сравнению с другими альтернативами управления состоянием, что делает его менее читабельным и менее удобным для сопровождения.

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

Первоначально опубликовано на https://aboutfrontend.blog 6 февраля 2023 г.