#1 Redux JS - Вступление

poster
Начинам знакомство с Redux - React библиотекой, которая сейчас у всех на слуху. В этом видео мы разберем что такое Redux JS на простом примере.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. В этом уроке мы рассмотрим такую библиотеку как redux. И первый вопрос, конечно, что это такое и зачем учить еще одну библиотеку о которой я никогда не слышал.

Итак redux - это предсказуемый контейнер состояния для javascript приложений. Он учит думать о приложении, как о начальном состоянии, которое изменяется последовательностью действий. И я, как и много других людей, считаю его очень хорошим подходом для javascript приложений.

Мы с вами будем рассматривать его вместе с react, так как они отлично сочетаются. React отвечает только за view слой в приложении, а redux хранение данных и работу с ними.

Но, вместо тысячи слов давайте лучше попробуем написать кусочек кода с использованием redux.

Для начала давайте установим redux в наш проект.

npm install redux --save --save-exact

Закомментируем пока содержимое файла index.js. И импортируем createStore из пакета redux.

import { createStore } from 'redux';

И попробуем создать store приложения.

const store = createStore();

Store - это наше хранилище всех данных в приложении. Любые данные, мы будем хранить в этом обьекте.

Если мы посмотрим в браузер, то увидим ошибку.

createStore.js:69 Uncaught Error: Expected the reducer to be a function.

Это потому, что на вход функции createStore нужно передать функцию, которая будет изменять наш store.

Допустим у нас будет приложение, которое работает с треками и плейлистами.

function playlist(state = []) {
  return state;
}

const store = createStore(playlist);

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

И первое, что нас интересует - это как выглядит наш store. Давайте законсолим его.

console.log(store.getState());

И сейчас это у нас пустой массив.

Теперь нас интересует, как нам подписаться на изменение нашего store, чтобы знать, что у нас изменились данные в нем. Очень просто. Для этого у стора есть subscribe метод.

store.subscribe(() => {
  console.log(store.getState());
})

Мы вызываем store.subscribe и передаем в него callback, который выстрелит, если у нас поменяется значение в store. И чтобы видеть, на какое значение оно поменяется, мы консолим store.getState.

Теперь давайте поменяем наше значение в store. В этом нам поможет функция dispatch. Это единственный способ поменять значение в store.

store.dispatch({ type: 'ADD_TRACK', payload: 'Smells like spirit' });

Функция dispatch принимает на вход обьект и единственное, но обязательное - это поле type. Собственно, dispatch - это action, то есть событие, а type - это тип этого события. В данном случае событие добавить трек. В поле payload содержатся данные.

Это еще не все, так как мы выстрелили action, но не отреагировали на него в нашей функции playlist. Давайте законсолим action в этой функции, который идет вторым аргументом.

function playlist(state = [], action) {
  console.log(action);
  return state;
}

Если мы посмотрим в браузер, то мы увидим 2 обьекта. Первый с типом @@redux/INIT, это событие, которые стреляет, когда redux инициализирован. Второй обьект - это как раз наш action. И мы видим в нем наш type и payload.

Давайте теперь добавим код, который будет менять наш стор. Для этого просто поставим условие, если type равняется ADD_TRACK, то добавляем значение в массив.

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

Как вы видите, я тут использовал оператор spread из es7, чтобы добавить значение в массив и вернуть новый массив. Это очень важно, так как наш стор иммутабельный, и это значит, что мы можем только создавать новую копию данных, а не менять старое состояние store. Это делает работу с данными очень просто и гибкой.

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

store.dispatch({ type: 'ADD_TRACK', payload: 'Enter Sandman' });

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

Давайте еще раз пройдем по тому, что мы сделали

  1. Создали новый store для нашего приложения
  2. Передали в него функцию, которая получает екшены и меняет store
  3. Подписались на изменения store с помощью функции subscribe
  4. Выстрелили action с данными
  5. Функция playlist меняет данные с store
  6. Теперь в callback функции subscribe мы всегда знаем, как выглядит наш стор и можем что-то перерисовать на странице.

Но об этом мы поговорим в следующем уроке.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Petr Pozhoga
1 месяц назад назад
Добрый день, правильно понимаю, что как только мы используем Redux то в Reacte нельзя пользоваться локальным стейтом и вся архитектура переносится в Redux в плоть до пагинации (количество страниц, текущая страница и т.д) ?
monsterlessons
1 месяц назад назад
Добрый день. Абсолютно наоборот. Нет никаких норм и стандартов. Используйте то, что вам нравится и когда вы видите в этом смысл. Используя на проекте Redux я стараюсь переносить все состояния кроме форм в Redux, просто по той причине, что дебажить 1 стейт проекта проще чем 2. И не нужно думать "А я тут пишу в локальный стейт или в redux?". Тогда для дебага мне достаточно посмотреть в devtools на экшены, чтобы понять в каком месте баг.
Moe Green
9 месяцев назад
Приступил к Redux. Мысли такие - поправьте меня, если я неправ. Забавно получается - во Vuex все находится в одном месте - state, mutations, actions. Actions пробрасываются в тот компонент, где они необходимы. В Redux сами actions не находятся в одном месте, а объявляются в том компоненте, в котором будут использоваться. И только потом они пробрасываются "назад", в reducer. Да? )
monsterlessons
9 месяцев назад
В Vuex все сводится к одному месту, но все можно разбить на отдельные файлы. В Redux actions могут находится где-угодно и использоваться где-угодно. Редьюсер просто слушает все экшены и по type вы можете изменять, что хотите.
Moe Green
9 месяцев назад
"... но все можно разбить на отдельные файлы." - да, там есть где поизвращаться с разбивкой ) Фактически - action-reducer - это обыкновенный паттерн Pub/Sub?
monsterlessons
9 месяцев назад
У него односторонний data flow. Этим он и лучше.
Moe Green
9 месяцев назад
благодарю! )
Moe Green
10 месяцев назад
И кстати - что вы думаете по поводу MobX? Один из поклонников React мне посоветовал смотреть в сторону MobX вместо Redux.
monsterlessons
10 месяцев назад
Кому то он нравится больше чем Redux. Я предпочитаю использовать Redux.
Moe Green
10 месяцев назад
"И первый вопрос конечно ..." - почему редУкс?! Вроде как редАкс должно быть. )) https://egghead.io/courses/getting-started-with-redux
monsterlessons
10 месяцев назад
Вы правы
Максим Сафаралиев
1год назад назад
Правильно ли я понимаю, что данные из API можно хранить в store? Например выгрузить из JSON список данных. Или такой подход не верный?
monsterlessons
1год назад назад
Этот подход абсолютно верный и именно для этих данных в 90% используется store. Также там можно хранить данные, нужные только на клиенте, данные из локалстораджа и вообще из любого ресурса данных.
Orlik
1год назад назад
Спасибо за качественный контент. У вас талант)
monsterlessons
1год назад назад
Спасибо. Очень приятно. Стараюсь.