React Redux

Использование с React 👩‍💻

С самого начала нужно подчеркнуть, что Redux не имеет отношения к React.

Вы можете писать приложения Redux с помощью React, Angular, Ember, jQuery или ванильного JavaScript.

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



Официальная React-Redux документация at https://react-redux.js.org содержат полное руководство о том, как использовать Redux и React вместе.

Установка

npm install react-redux redux

Eсли вы создаете новое приложение с помощью create-react-app

можно воспользоваться флагом --template.

npx create-react-app my-app --template redux

Почитать подробнее о шаблонах можно тут.

Provider

React Redux предоставляет <Provider />, который делает хранилище Redux доступным для остальной части вашего приложения:

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

connect()

React Redux предоставляет вам функцию подключения для подключения вашего компонента к магазину.

Обычно вы вызываете connect следующим образом:

import { connect } from "react-redux";
import { increment, decrement, reset } from "./actionCreators";
// const Counter = ...
const mapStateToProps = (state /*, ownProps*/) => {
return {
counter: state.counter,
};
};
const mapDispatchToProps = { increment, decrement, reset };
export default connect(mapStateToProps, mapDispatchToProps)(Counter);

Сигнатура функции connect:

  • Первый параметр - функция, которая собирает нужную информацию из хранилища (в функцию передается текущее состояние хранилища) и возвращает объект с ключами, которые вам нужны в props.`
  • Второй параметр - объект, в котором ключами будут опять же свойства в props, а значениями - actionCreator-ы. connect автоматически обернет ваши actionCreator в dispatch, после чего можно спокойно вызывать this.props.actionName() - это вызовет store.dispatch(actionName())

connect возвращает функцию, которая из любого компонента сделает компонент-обертку с вышеуказанными настройками.

app with redux

Counter with redux step by step

  1. Создаем Reducer
1import { combineReducers } from "redux";
2
3const initialState = { value: 0 };
4const counter = (state = initialState, action) => {
5 if (action.type === "increment") {
6 return {
7 ...state,
8 value: state.value + 1,
9 };
10 }
11 return state;
12};
13
14export default combineReducers({ counter });

combineReducers(reducers)

Как только ваше приложение становится все более сложным, вы захотите разделить ваш функцию редюсер на отдельные функции, которые управляют независимыми частями состояния.

Функция combineReducers преобразует объект, значениями которого являются различные функции редюсеры, в одну функцию редюсер, которую можно передать в метод createStore.

Результирующий редюсер вызывает вложенные редюсеры и собирает их результаты в единый объект состояния. Состояние, созданное именами combineReducers(), сохраняет состояние каждого редуктора под их ключами, переданные в combineReducers()

  1. Создаем Redux store
1import { createStore } from "redux";
2import rootReducer from "./rootReducer";
3
4const store = createStore(rootReducer);
5
6export default store;

createStore(reducer, [preloadedState], [enhancer])

Создает Redux стор которое хранит полное дерево состояния вашего приложения. Оно должно быть единственным стором в вашем приложении.

  1. Cоздаем компонент Counter
1import React from "react";
2import { connect } from "react-redux";
3
4// Props компонента приходят из функции connect
5
6const Counter = ({ count, increment }) => {
7 return (
8 <div>
9 <h1>Counter</h1>
10 <h2>{count}</h2>
11 <button onClick={increment}>Increment</button>
12 </div>
13 );
14};
15
16// Создаем функцию mapStateToProps которая будет транформировать состояние из Redux стора в props компонента Counter
17const mapStateToProps = (state) => ({
18 count: state.counter.value,
19});
20
21//Создаем функцию mapDispatchToProps которая будет передавать actionCreatord обернутые dispatch в props компонента Counter
22const mapDispatchToProps = (dispatch) => ({
23 increment: () => dispatch({ type: "increment" }),
24});
25
26export default connect(mapStateToProps, mapDispatchToProps)(Counter);
  1. Оборачиваем наше приложение в Provider и передаем store
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { Provider } from "react-redux";
import store from "./configureStore";
const rootElement = document.getElementById("root");
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
rootElement
);
  1. Добавляем компорент Counter в App
import React from "react";
import Counter from "./Counter";
export default function App() {
return (
<div className="App">
<Counter />
</div>
);
}

Полный код

Практика 👩‍💻👨‍💻

Используя код Counter, добавить следующий функционал

  • Добавить функцию decrement
  • Добавить функцию reset

Почитать 📚

Посмотреть 👀

ДЗ 🏡

CountDown component

Пользуясь лецией Жизненый цикл компонента

Реализовать <CountDown/> компонент с использованием redux.

Должен иметь следующие actions:

  • start
  • reset
  • stop
  • update
Edit this page on GitHub