Конечно, вы можете, во-первых, давайте удостоверимся, что концепции понятны.
Redux уже имеет «состояние», поэтому копирование его во внутреннее состояние является избыточным.
connect()
:
Этот удобный метод используется для сопоставления состояния избыточности с подпорками в вашем компоненте. То есть вы не копируете состояние в другое состояние, вы используете состояние Redux в качестве реквизита, которое является неизменным и больше похоже на ссылку на реальные данные внутри Redux.
Он построен по шаблонному вызову hoc , но это урок для другого вопроса. Важная вещь, которую нужно знать о hoc, заключается в том, что он принимает компонент в качестве аргумента и возвращает новый компонент, улучшенный.
mapStateToProps()
:
Это будет вашим способом сообщить connect
какую часть состояния избыточности вы хотите получить внутри своего компонента. Это метод, который получает полное состояние избыточности, извлекает свойства, которые вы хотите использовать, и возвращает их для отправки в качестве реквизитов в ваш компонент.
Теперь вы упускаете одну ключевую часть эквалайзера, а именно редукса ...
Provider
Эта часть должна обернуть все ваше приложение (или ту его часть, к которой вы хотите, чтобы он имел доступ с избыточным доступом, который обычно является всем этим), и именно оно отвечает за отправку хранилища избыточного кода по дереву, чтобы connect
мог его захватить. позже (это достигается через context реакции , но это еда для другой даты).
Вы получаете своего провайдера, как: import {Provider} from 'react-redux';
, а затем вы даете ему магазин в качестве опоры, называемой .... store
(умный, верно?)
Достаточно чата, ладно, приступим к делу.
Начнем с импорта, давайте получим все, что нам нужно:
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import {Provider, connect} from 'react-redux';
Мы добавили еще две вещи: компонент Provider
и connect
hoc.
var initialState = {
qty: 0,
price: 0
}
function changeState(state = initialState, action) {
switch (action.type) {
case 'INCREMENT':
var stateCopy1 = Object.assign({}, state);
stateCopy1.qty = stateCopy1.qty + action.qty;
stateCopy1.price = stateCopy1.price + action.price;
return stateCopy1;
default:
return state;
}
}
var store = createStore(changeState);
Теперь, вы видели, что там произошло? Именно так! Ничего такого. Ваш редуктор может оставаться как есть, мы не двигаемся, хотя для более крупного приложения вы можете научиться комбинировать редукторы
class Home extends React.Component {
render() {
return (
<Provider store={store}>
<Comp1 /><br />
<Comp2 />
</Provider>
)
}
}
Хорошо, ваш Fragment
исчез, я сожалею об этом, но теперь он больше не нужен. Fragment
s используются для возврата двух или более компонентов, но поскольку Provider
теперь оборачивает компоненты, нет необходимости использовать Fragment
.
А что касается Provider
, вам просто нужно поместить его вне всего и дать ему store
. Достаточно просто.
class Comp1 extends React.Component {
increase = () => {
var action = {
type: 'INCREMENT',
qty: 1,
price: 100
}
store.dispatch(action);
}
render() {
return (
<button type="button" onClick={this.increase}>Increase</button>
)
}
}
В этом последнем компоненте мы ничего не двигали. Хотя мы должны были, посмотрите, как вы используете store
напрямую для dispatch
вашего action
. В обычном приложении этот компонент был бы в другом файле, поэтому у вас не было бы доступа к свойству store
. И вот снова приходит наш друг connect
, который помогает нам отправлять действия через функцию под названием mapDispatchToProps
, о которой вы читаете здесь , но это также для другого дня.
А вот и все, чего мы все ждали, метод connect
:
class Comp2 extends React.Component {
render() {
return (
<div>
<h1>Total items in cart: {this.props.qty}</h1>
<h1>Total price of cart :{this.props.price}</h1>
</div>
)
}
}
function mapStateToProps( state ){
return { qty: state.qty, price:state.price }
}
Comp2 = connect(mapStateToProps)(Comp2);
Это может немного сбивать с толку, поэтому позвольте мне объяснить:
Сначала мы удалили все, что связано с состоянием вашего компонента. Мы больше не используем его, потому что это то, что вы хотели, верно? А также компонент теперь стал меньше. И круче.
Но что случилось позже? ну, во-первых, мы определяем функцию mapStateToProps
. И это переводит состояние избыточности в состояние ваших компонентов. На этот раз мы отправляем каждое свойство из состояния избыточности в ваш компонент, но в более крупном приложении этого не произойдет, в более крупном приложении избыточность будет иметь состояние всего внутри, это могут быть элементы корзины, тема приложения. цвета, информация о пользователе и т. д. Многое, поэтому внутри этой функции мы выбираем только те свойства, которые нам интересны, чтобы попасть внутрь нашего компонента.
Теперь вызов connect ... мы переопределяем наш компонент, и это немного странно, но я попытаюсь объяснить.
connect
получил наш метод mapStateToProps
, а затем наш компонент. И они спарились внутри connect
и дали начало другому компоненту, этот компонент будет иметь компонент, который мы сначала определили как дочерний, и всегда будет отправлять ему части состояния избыточности, которые мы просили, как реквизиты.