Введение в React-Redux

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

Прежде чем перейти к React-Redux, важно понять, что такое Redux и зачем он нужен.

Что такое Redux?

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

Redux основан на трёх основных принципах:

  1. Единый источник правды (Single Source of Truth): всё состояние приложения хранится в одном JavaScript-объекте, называемом store.
  2. Состояние доступно только для чтения (State is Read-Only): изменить состояние можно только путём отправки action — объекта, описывающего изменение.
  3. Изменения выполняются с помощью чистых функций (Changes are Made with Pure Functions): трансформации состояния выполняют reducers — чистые функции, которые принимают предыдущее состояние и action, а возвращают новое состояние.

Зачем использовать React-Redux?

React-Redux — официальная библиотека для подключения Redux к React. Ниже перечислены причины, по которым разработчики выбирают React-Redux:

  • Упрощение управления состоянием: React-Redux организует обработку изменений состояния, позволяя централизованно контролировать их, что облегчает отслеживание изменений во всём приложении.
  • Предсказуемый поток состояния: Redux гарантирует, что состояние меняется только через действия, обрабатываемые редьюсерами, что делает процесс прозрачным и удобным для отладки.
  • Разделение UI-компонентов и логики состояния: React-Redux позволяет компонентам сосредоточиться на отображении UI, тогда как Redux управляет состоянием.
  • Упрощённая отладка: благодаря поддержке инструментов, таких как Redux DevTools, вы можете просматривать, логировать и возвращать изменения состояния, что значительно ускоряет процесс отладки.
  • Оптимизация производительности: React-Redux применяет shallow equality checks [поверхностное сравнение], чтобы обновлять компоненты только при действительно изменившемся состоянии, предотвращая лишние ререндеры.

Основные концепции React-Redux

Для эффективного использования React-Redux необходимо знать ключевые понятия:

1. Store

Store — централизованный объект, содержащий состояние приложения. Изменять состояние можно только через store.

2. Actions

Action — простой JavaScript-объект, описывающий изменение состояния. Он обязательно содержит свойство type и при необходимости — payload.

const incrementAction = {
    type: 'INCREMENT',
    payload: 1
};

3. Reducers

Reducer — чистая функция, описывающая, как изменяется состояние в ответ на действие. Она принимает текущее состояние и action, возвращая новое состояние.

const counterReducer = (state = 0, action) => {
    switch (action.type) {
        case 'INCREMENT':
            return state + action.payload;
        case 'DECREMENT':
            return state - action.payload;
        default:
            return state;
    }
};

4. Dispatch

Функция dispatch используется для отправки действий (actions) в Redux store, инициируя работу редьюсера для обновления состояния.

store.dispatch(incrementAction);

5. Selectors

Selector — функция, которая извлекает определённые данные из состояния Redux store. Это упрощает доступ к состоянию и способствует поддерживаемости кода.

const selectCount = (state) => state.count;

6. Provider

Компонент Provider предоставляет Redux store всем компонентам приложения. Его следует обернуть вокруг всего приложения, чтобы обеспечить доступ к store из любого компонента.

import { Provider } from 'react-redux';

<Provider store={store}>
    <App />
</Provider>;

7. connect()

Функция connect() из React-Redux предназначена для подключения React-компонентов к Redux store. Она позволяет компонентам получать доступ к состоянию и отправлять действия.

import { connect } from 'react-redux';

const Counter = ({ count, increment }) => (
    <div>
        <h1>{count}</h1>
        <button onClick={increment}>Increment</button>
    </div>
);

const mapStateToProps = (state) => ({
    count: state.count
});

const mapDispatchToProps = (dispatch) => ({
    increment: () => dispatch({ type: 'INCREMENT', payload: 1 })
});

export default connect(mapStateToProps, mapDispatchToProps)(Counter);

Как работает React-Redux

React-Redux связывает React-компоненты и Redux store, обеспечивая комфортное управление состоянием во всем приложении. Поясним процесс по шагам:

1. Создание Store

Redux store содержит всё состояние приложения. Его создают с помощью функции createStore() и инициализируют редьюсером — функцией, управляющей изменениями состояния.

const store = createStore(counterReducer);

2. Отправка Actions

Actions — простые объекты, описывающие изменения состояния. Они отправляются в Redux с помощью dispatch, уведомляя об изменениях.

store.dispatch({ type: 'INCREMENT', payload: 1 });

3. Редьюсеры обновляют состояние

Reducer обновляет состояние в зависимости от типа действия. Он получает текущее состояние и action, возвращая новое состояние.

const counterReducer = (state = 0, action) => {
    switch (action.type) {
        case 'INCREMENT': return state + action.payload;
        default: return state;
    }
};

4. Подключение компонентов с connect()

Функция connect() позволяет связать React-компоненты с Redux store для доступа к состоянию и отправки действий.

const mapStateToProps = (state) => ({ count: state });
const mapDispatchToProps = (dispatch) => ({
    increment: () => dispatch({ type: 'INCREMENT', payload: 1 })
});

5. Использование Provider для предоставления доступа к Store

Компонент Provider делает store доступным всем компонентам приложения.

<Provider store={store}><App /></Provider>

6. Ререндеры и реактивность

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

Шаги по внедрению React-Redux

Шаг 1: Создание проекта

Сначала создайте новое React-приложение с помощью create-react-app:

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

Затем установите redux и react-redux:

npm install redux react-redux

Структура папок

Структура папок

Зависимости

"dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-redux": "^9.1.2",
    "react-scripts": "5.0.1",
    "redux": "^5.0.1",
    "web-vitals": "^2.1.4"
}

Шаг 2: Определите типы actions

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

// src/redux/actionTypes.js
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';

Шаг 3: Создайте action creators

Action creators — это функции, возвращающие объекты actions.

// src/redux/actions.js
import { INCREMENT, DECREMENT } from "./actionTypes";

export const increment = () => ({
    type: INCREMENT,
});

export const decrement = () => ({
    type: DECREMENT,
});

Шаг 4: Напишите редьюсер

Редьюсер описывает, как изменяется состояние приложения в ответ на действия. Он принимает текущее состояние и action и возвращает обновлённое состояние.

// src/redux/reducer.js
import { INCREMENT, DECREMENT } from "./actionTypes";

const initialState = {
    count: 0,
};

const counterReducer = (state = initialState, action) => {
    switch (action.type) {
        case INCREMENT:
            return { ...state, count: state.count + 1 };
        case DECREMENT:
            return { ...state, count: state.count - 1 };
        default:
            return state;
    }
};

export default counterReducer;

Шаг 5: Создайте Redux store

Создайте Redux store с помощью функции createStore.

// src/redux/store.js
import { createStore } from 'redux';
import counterReducer from './reducer';

const store = createStore(counterReducer);

export default store;

Шаг 6: Оберните приложение в Redux Provider

Оберните всё приложение компонентом Provider, чтобы обеспечить доступ к store во всех компонентах.

// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './redux/store';
import App from './App';

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);

Шаг 7: Создайте главный компонент App

// src/App.js
import React from "react";
import Counter from "./components/Counter";

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

export default App;

Шаг 8: Создайте компонент Counter

// src/components/Counter.js
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { increment, decrement } from "../redux/actions";

const Counter = () => {
    const count = useSelector((state) => state.count);
    const dispatch = useDispatch();

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={() => dispatch(increment())}>Increment</button>
            <button onClick={() => dispatch(decrement())}>Decrement</button>
        </div>
    );
};

export default Counter;

Для запуска приложения выполните команду:

npm start

Вывод

Интерфейс React-Redux Counter

Заключение

В этой статье мы рассмотрели React-Redux, который упрощает управление состоянием в React, централизуя его в Redux store. Используя Provider, connect() и хуки React-Redux — useSelector и useDispatch, компоненты React получают удобный доступ к глобальному состоянию и могут его обновлять. React-Redux помогает повысить предсказуемость состояния, производительность и удобство поддержки, особенно в больших приложениях.

🔑 Ключевые моменты:

  • Redux управляет состоянием через единственный store, обеспечивая предсказуемость и централизованность.
  • React-Redux соединяет Redux c React, упрощая доступ к состоянию и отправку действий.
  • Компоненты React отделены от логики управления состоянием благодаря React-Redux.
  • Хуки useSelector и useDispatch заменяют connect() и делают код легче для восприятия.
  • Поддержка инструментов отладки и оптимизации ререндеров повышает качество и производительность приложений.

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *