#2 Redux JS - отрисовываем елементы из store

poster
Мы продолжаем изучать Redux - React. В этом уроке мы отрендерим форму добавления треков и список треков из store.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. Как в комментариях правильно указали по русски правильно называть библиотеку редакс а не редукс. Поэтому в этом уроке мы продолжаем разбираться с редаксом. И сегодня мы добавим форму, которая будет выводить список наших треков.

Добавим в html разметку базовую форму добавления треков в список. Добавим input для ввода треков, кнопку добавление трека и контейнер для списка треков.

<div>
  <input type="text" class="trackInput"/>
  <button class="addTrack">Add track</button>
  <ul class="list"></ul>
</div>

Теперь повесим listener на кнопку добавить трек. Давайте найдем эту кнопку на странице. Так как querySelectorAll возвращает массив, нам нужен первый елемент.

const addTrackBtn = document.querySelectorAll('.addTrack')[0];

Теперь давайте повесим addEventListener на кнопку. Вторым аргументом у нас идет функция, в которой мы хотим что-то сделать. Мы хотим найти название трека, которое мы ввели в input. И консолим trackName.

addTrackBtn.addEventListener('click', () => {
  const trackName = document.querySelectorAll('.trackInput')[0].value;
  console.log('track name', trackName);
});

Если мы посмотрим в браузер, то видим, что у нас отрисовалась кнопки и input. И если мы что-то введем в input и нажмем add Track, в консоли у нас отображается имя введенного трека.

Теперь добавим dispatch имени трека

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

Теперь в консоли у нас выводится измененный стор с новым треком. Теперь мы хотим зарендерить список треков из store. Добавим в функции subscribe вывод массива. Найдем сначала елемент list. Потом пройдемся циклом по store.getState(). Создаем новый елемент li. Пишем текст в li и добавляем li к нашему листу.

store.subscribe(() => {
  console.log('subscribe', store.getState());
  const list = document.querySelectorAll('.list')[0];
  store.getState().forEach(track => {
    const li = document.createElement('li');
    li.textContent = track;
    list.appendChild(li);
  })
})

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

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

list.innerHTML = '';

Теперь у нас добавляются правильные елементы. Теперь единственно, что работает неправильно - это то, что наш input не очищается. Давайте добавим это.

document.querySelectorAll('.trackInput')[0].value = '';

Теперь все работает отлично. Наш список рендерится так как он находится в store.

И давайте порефакторим немного код, чтобы у нас не дублировался поиск DOM елементов. Вынесем наверх кода нахождение списка, инпута и кнопки так как эти елементы никогда не меняются.

const addTrackBtn = document.querySelectorAll('.addTrack')[0];
const list = document.querySelectorAll('.list')[0];
const trackInput = document.querySelectorAll('.trackInput')[0];

Уберем консоли и изменим оставшийся код

store.subscribe(() => {
  list.innerHTML = '';
  trackInput.value = '';
  store.getState().forEach(track => {
    const li = document.createElement('li');
    li.textContent = track;
    list.appendChild(li);
  })
})

addTrackBtn.addEventListener('click', () => {
  const trackName = trackInput.value;
  store.dispatch({ type: 'ADD_TRACK', payload: trackName });
});

Вот так легко с редаксом мы реализовали store, actions и перерисовку DOM елементов.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Nastya
4 месяцев назад
Для чего писать document.querySelectorAll('.list')[0], если есть document.querySelector('.list')? Что за трек "Smells like spirit"?))) Может быть "Smells like teen spirit"?)
monsterlessons
4 месяцев назад
Да вы правы в обоих случаях.
Zato Prosto
11 месяцев назад
Я правильно понял, что в React методы стора subscribe() и getState() не будут исопльзоваться?
monsterlessons
11 месяцев назад
getState используется. subscribe намного реже.
Rustam Apaev
1год назад назад
Redux всегда был связан с React в моём воображении )) этот урок, где вдруг кнопки и события создаются голым JavaScript очень удивил) По правде сказать я очень обрадовался, потому что аналогичные задачи делал только в ES5 + JQuery. Как всё это делается в ES6 - очень интересно)
monsterlessons
1год назад назад
Я считаю, что это большой минус, что в большинстве туториалов даже не обьясняется, что React к Redux абсолютно не обязателен, да и простой пример того, как работает Redux проще показать без Реакта. Вот кстати серия по ES6, если еще не смотрели, возможно будет интересно. https://monsterlessons.com/project/series/es6-dlya-nachinayushih
Rustam Apaev
1год назад назад
да, согласен. Мне нравится ваш стиль, вы всегда показываете суть вещей, например делаете что-то одно, потом добавляете, исправляете и становится ясна суть явления. С редуксом так же получилось. Я наконец оценил саму его идею. Может и потому что уже начаальный уровень какой-то есть. Когда я прошлый раз проходил учебник где реакт и редукс разбирались, я изначально запутался в настройках вебпака для хот-релоада, разных вспомогательных пакетов, а потом в самом реакте и редуксе) все свалилось одной кучей на меня, я даже не понимал, что больше мне непонятно. А сейчас я прошел ES6 синтаксис, потом Реакт и теперь Редукс начал и всё по полочкам уложилось вроде. Даже в первый раз в жизни уроки программирования в тетрадку законспектировал и периодически подглядываю в конспекты :-)
monsterlessons
1год назад назад
Спасибо за отзыв. Я стараюсь, чтобы урок всегда был понятен и с реальными примерами. Рад, что мои уроки помогли.
laert
2 лет назад
Почему в браузере выбивает ошибку Uncaught TypeError: Cannot read property 'addEventListener' of undefined Как решить?
monsterlessons
2 лет назад
Это значит, что елемента, на который вы навешиваете addEventListener у вас не существует. Попробуйте посмотреть исходный код урока и сравнить с своим.