Table of Contents
Использование с 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
возвращает функцию, которая из любого компонента сделает компонент-обертку с вышеуказанными настройками.
Counter with redux step by step
- Создаем Reducer
1import { combineReducers } from "redux";23const 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};1314export default combineReducers({ counter });
combineReducers(reducers)
Как только ваше приложение становится все более сложным, вы захотите разделить ваш функцию редюсер на отдельные функции, которые управляют независимыми частями состояния.
Функция combineReducers преобразует объект, значениями которого являются различные функции редюсеры, в одну функцию редюсер, которую можно передать в метод createStore.
Результирующий редюсер вызывает вложенные редюсеры и собирает их результаты в единый объект состояния. Состояние, созданное именами combineReducers(), сохраняет состояние каждого редуктора под их ключами, переданные в combineReducers()
- Создаем Redux store
1import { createStore } from "redux";2import rootReducer from "./rootReducer";34const store = createStore(rootReducer);56export default store;
createStore(reducer, [preloadedState], [enhancer])
Создает Redux стор которое хранит полное дерево состояния вашего приложения. Оно должно быть единственным стором в вашем приложении.
- Cоздаем компонент Counter
1import React from "react";2import { connect } from "react-redux";34// Props компонента приходят из функции connect56const 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};1516// Создаем функцию mapStateToProps которая будет транформировать состояние из Redux стора в props компонента Counter17const mapStateToProps = (state) => ({18 count: state.counter.value,19});2021//Создаем функцию mapDispatchToProps которая будет передавать actionCreatord обернутые dispatch в props компонента Counter22const mapDispatchToProps = (dispatch) => ({23 increment: () => dispatch({ type: "increment" }),24});2526export default connect(mapStateToProps, mapDispatchToProps)(Counter);
- Оборачиваем наше приложение в 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);
- Добавляем компорент Counter в App
import React from "react";import Counter from "./Counter";export default function App() {return (<div className="App"><Counter /></div>);}
Полный код
Практика 👩💻👨💻
Используя код Counter
, добавить следующий функционал
- Добавить функцию
decrement
- Добавить функцию
reset
Почитать 📚
- Redux official documentation
- Краткое руководство по Redux для начинающих
- Redux: шаг за шагом
- Redux hooks
Посмотреть 👀
ДЗ 🏡
CountDown component
Пользуясь лецией Жизненый цикл компонента
Реализовать <CountDown/>
компонент с использованием redux.
Должен иметь следующие actions:
- start
- reset
- stop
- update