Редьюсеры и connect

Создание Reducer

Создадим "корневой редьюсер" (rootReducer).
src/reducers/index.js
1
export const initialState = {
2
user: 'Unknown User',
3
}
4
5
export function rootReducer(state = initialState) {
6
return state
7
}
Copied!
В этой функции нечего комментировать. Просто возвращается {user: 'Unknown User'} (неизвестный пользователь).
В дальнейшем мы будем комбинировать редьюсеры в корневом редьюсере, но сейчас нам важно отобразить имя юзера (Unknown User) в компоненте, чтобы вы не заскучали от чтения.
Главное, что нужно сейчас держать в голове: корневой редьюсер - это и есть представление всего нашего состояния приложения (то есть, всего нашего store).
Сконфигурируем store:
src/store/configureStore.js
1
import { createStore } from 'redux'
2
import { rootReducer, initialState } from '../reducers'
3
4
export const store = createStore(rootReducer, initialState)
Copied!
Не забывайте, сигнатура функции createStore:
  • первый аргумент - функция-обработчик изменений (редьюсер)
  • второй аргумент - начальное состояние

Связывание данных из store с компонентами приложения

В разделе Точка входа шла речь о некой функции connect, которая поможет нам получить в качестве props для компонента <App /> данные из store. Добавим ее:
src/App.js
1
import React, { Component } from 'react'
2
import { connect } from 'react-redux'
3
import './App.css'
4
5
class App extends Component {
6
render() {
7
return (
8
<div className="App">
9
<header className="App-header">
10
<h1 className="App-title">Мой топ фото</h1>
11
</header>
12
<p className="App-intro">Здесь будут мои самые залайканые фото</p>
13
<p>Меня зовут: {this.props.user}</p> {/* добавлен вывод из props */}
14
</div>
15
)
16
}
17
}
18
19
// приклеиваем данные из store
20
const mapStateToProps = store => {
21
console.log(store) // посмотрим, что же у нас в store?
22
return {
23
user: store.user,
24
}
25
}
26
27
// в наш компонент App, с помощью connect(mapStateToProps)
28
export default connect(mapStateToProps)(App)
Copied!
Назначение функции connect вытекает из названия: подключи React компонент к Redux store.
Результат работы функции connect - новый присоединенный компонент, который оборачивает переданный компонент.
У нас был компонент <App />, а на выходе получился <Connected(App)>. В этом не трудно убедиться, если взглянуть в react dev tools.
app-with-unknown-user
Взгляните на правую часть скриншота, и вы увидите, что в свойствах (props) нашего компонента <App /> теперь есть метод redux store - dispatch, и объект свойств (в нашем случае, пока что строка) user. Это так же результат работы функции connect.
Давайте еще поиграемся с простым примером. Для начала изменим набор данных:
src/reducers/index.js
1
export const initialState = {
2
user: { // мы вложили в user вместо строки, объект
3
name: 'Василий',
4
surname: 'Реактов',
5
age: 27,
6
},
7
}
8
9
export function rootReducer(state = initialState) {
10
return state
11
}
Copied!
затем подкрутим компонент:
src/containers/App.js
1
// ... (импорты)
2
3
class App extends Component {
4
render() {
5
const { name, surname, age } = this.props.user
6
return (
7
<div className="App">
8
<header className="App-header">
9
<h1 className="App-title">Мой топ фото</h1>
10
</header>
11
<p>
12
Привет из App, {name} {surname}!
13
</p>
14
<p>Тебе уже {age} ?</p>
15
</div>
16
)
17
}
18
}
19
20
// ... (mapStateToProps и connect - не изменились)
Copied!
Все работает ровно так, как мы указали: в объект user "подключилось" все состояние нашего приложения, которое сейчас очень простое и описано в src/reducer/index.js.
hello-vasily-reactov
Итого: мы научились "вытаскивать" данные из стора в компонент, с помощью connect.
Исходный код на текущий момент.
Прежде чем мы перейдем к созданию actions и взаимодействию пользователя со страницей, давайте поговорим о комбинировании редьюсеров (combineReducers) и создадим реальную структуру нашего будущего приложения в следующем уроке.

Полезные ссылки:

  • connect (офф.документация)