#3 Redux JS - connect в react-redux

poster
В этом уроке мы разберем как подключить в react приложении наш store из redux. Как подписаться в react компоненте на изменение нашего store и перерисовать компонент.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. В этом уроке мы разберем как же соединить redux и react. Для начала нам нужно установить пакет react-redux

npm install react-redux --save --save-exact

Теперь все наше дерево компонентов в react должно иметь доступ к redux store и мочь подписываться на него. Для того, чтобы не прокидывать store в каждый компонент руками. Рекомендуемым способом пробрасывания store является использование компонента Provider, который выступает в роли рутового компонента.

Давайте закомментируем код, который мы с вами писали в прошлом уроке из index.js и расскомментируем старый код. Теперь импортируем компонент Provider из react-redux и createStore из redux.

import { Provider } from 'react-redux'
import { createStore } from 'redux'

createStore мы с вами использовали на прошлом уроке, а Provider - это как раз наш рутовый компонент, чтобы прокидывать store.

теперь скопируем код для создания store из прошлого урока.

function playlist(state = [], action) {
  if (action.type === 'ADD_TRACK') {
    return [
      ...state,
      action.payload
    ];
  }
  return state;
}

const store = createStore(playlist);

Кстати функцию playlist, которую передают при создании store - называют reducer. Почему - мы разберем с вами чуть позже.

Теперь единственное, что осталось это завраппить наш App в Provider и передать ему store в качестве аргумента. Теперь этот store будет доступен в каждой компоненте react.

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

В уроках по react мы с вами уже разбирали, что компоненты можно разделить на smart компоненты и dumb компоненты. Smart - это те, которые манипулируют данными и dumb - это те, которые только что-то отрисовывают.

Давайте сделаем нашу App компоненту smart. Это логично, так как эта главная компонента на нашей странице. Уберем стили и классы. У нас получилось пустая компонента. Для этого импортируем connect декоратор из react-redux.

import { connect } from 'react-redux'

и применяем этот декоратор к классу App.

export default connect(
  state => ({}),
  dispatch => ({})
)(App);

Итак этот декоратор принимает на вход 2 функции. В первой аргумент будет state, а в второй dispatch. Он возвращает функцию, в которую мы передаем наш компонент App. Давайте разберем подробнее первую функцию.

Первая функция обычно называется mapStateToProps. Потому что она маппит state, то есть состояние нашего store в props react компонента. Это позволяет очень легко подписываться на стор в компоненте и следить за его изменением.

Давайте вернем в этой функции переменную testStore в которую запишем state.

export default connect(
  state => ({
    testStore: state
  }),
  dispatch => ({})
)(App);

State и является глобальным состоянием нашего store. И законсолим переменную this.props.testStore в render функции

console.log(this.props.testStore);

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

Теперь давайте изменим наш store, добавив в него по умолчанию 2 трека.

const initialState = [
  'Smells like spirit',
  'Enter Sandman'
];

function playlist(state = initialState, action) {
  if (action.type === 'ADD_TRACK') {
    return [
      ...state,
      action.payload
    ];
  }
  return state;
}

Мы создали массив initialState и передали его в reducer playlist. В консоли браузера мы видим, что нам вывелось 2 трека.

Если мы посмотрим в браузер, то увидим, что в консоли вывелись эти два трека. Давайте скопируем из index.html нашу форму с добавлением трека и отрисуем ее в App компоненте. Удалим все классы.

<div>
  <input type="text" />
  <button>Add track</button>
  <ul>
  </ul>
</div>

Давайте отрисуем треки как обычные данные в react.

{this.props.testStore.map((track, index) =>
  <li key={index}>{track}</li>
)}

Как мы видим мы успешно вывели данные из store в наш компонент. И частично перенесли функционал с чистого javascript на react.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Игорь Белогуров
9 месяцев назад
Все-таки, если подавать материал новичкам, не стоит пренебрегать нормальным именованием переменных и функций, а не показывать mapstate и dispatch to props на примере анонимных функций, использовать рефы (которые уже давно считаются антипаттерном). Да и в принципе не очень понятно донесена мысль зачем нам вообще нужен коннект и как можно иначе передавать, скажем, стор. В целом, уроки полезные, но скорее для тех, кто уже разбирается. Те, кто вообще не слышал и хочет разобраться - пейлоад, выстреливает экшен, диспатч - сходу такими вещами лучше не разбрасываться.
monsterlessons
9 месяцев назад
Спасибо за отзыв, но до вас пока никто не жаловался, если бы таких отзывов было много, то я бы делал видео проще.
Karen Kostanyan
2 лет назад
Зачем react-dedux dispatch , если есть локальный state ?
monsterlessons
2 лет назад
Подход redux позволяет делать однонаправленный флоу данных и хранить все данные в одном месте, откуда их можно везде читать. Локальный стейт не дает такой возможности.
Karen Kostanyan
2 лет назад
везде читать ты имеешь виду если я например в App componet у мне изменятся что то по this.props.testStore и например у меня есть еще один компонент About который использую в App и в About тоже изменятся что то по this.props.testStore, и когда я делаю dispatch то и в App и в About одновременно изменятся все???? Ты это имеешь виду ?
monsterlessons
2 лет назад
Обычно dispatch делают, чтобы поменять данные в store. connect позволяет в компонентах подписываться на любые данные из store. Например App и About могут подписаться на любые данные. Даже на одни и те же данные.
OmniWeb
2 лет назад
А зачем писать --save-exact? На гитхабе пакета react-redux указано просто npm install --save react-redux
monsterlessons
2 лет назад
--save-exact устанавливает точную версию пакета в package.json. Это защищает от установки более новой версии пакета с багами. Стоит заметить, что даже при точной версии пакета, что-то может поломаться, так как от вас не зависит какие зависимости и как установил ваш пакет. Например, вы устанавливаете пакет, который имеет зависимости не точных версий. Если зависимость обновится и поломается, то поломается и пакет, который вы установили. Для того, чтобы этого избежать используют npm shrinkwrap или yarn.lock.