Отправка action в Redux приложении

Теперь у нас есть редьюсер для обновления слайса с реакциями. Сейчас нам необходимо добавить отправку action, которая будет срабатывать при клике пользователя по кнопке с реакцией. Но прежде, чтобы все полностью работало, нам нужно внести пару изменений.

Давайте откроем наше приложение с продуктами, а в нем файл productsSlice.js. Посмотрите на определение initialState. Видите? В объектах нет свойства с реакциями. Давайте это исправим, установив счетчики каждой из реакций в 0:

products/productsSlice.js{
  id: '1',
  title: 'Product1',
  desc: 'This is an amazing product',
  price: '300',
  amount: '30',
  reactions: {
    good: 0,
    soso: 0,
    bad: 0,
  },
},

Во второй объект для инициализации добавьте свойство reactions сами. Это же свойство нам необходимо добавить ниже в код для редьюсера productAdded, чтобы в новых продуктах тоже был такой функционал. Давайте сделаем это для его метода prepare:

products/productsSlice.jsprepare(title, desc, price, amount, sellerId) {
  return {
    payload: {
      id: nanoid(),
      title,
      desc,
      price,
      amount,
      seller: sellerId,
      reactions: {
        good: 0,
        soso: 0,
        bad: 0,
      },
    },
  }
},

Теперь приступим к отправке action. Откроем файл UserReactions.jsx, затем импортируем в него хук useDispatch и reactionClicked:

products/UserReactions.jsximport { useDispatch } from 'react-redux'
import { reactionClicked } from './productsSlice'

В начале кода в теле функции UserReactions первой строчкой (перед const userReactions ...) пропишем:

products/UserReactions.jsxconst dispatch = useDispatch()

И навесим на кнопку реакции отправку reactionClicked при клике, при этом у нас будет передаваться id продукта и название реакции, по которой кликнули:

products/UserReactions.jsx<button
  key={name}
  type="button"
  className="reaction-button"
  onClick={() =>
    dispatch(reactionClicked({ productId: product.id, reaction: name }))
  }
>
  {image} {product.reactions[name]}
</button>

Нам осталось теперь вывести компонент с реакциями в верстке для наших страничек. Сделаем это в файле ProductsList.jsx перед элементом Link:

products/ProductsList.jsx<UserReactions product={product} />

И точно также перед элементом Link на страничке продукта в файле ProductPage.jsx:

products/ProductPage.jsx<UserReactions product={product} />

Теперь, когда все встало на свои места, мы можем запустить наше приложение. Попробуем покликать на кнопочки с реакциями. Можем добавить новый продукт и также понажимать на них. Теперь, где бы мы не кликали по кнопкам с реакциями, измененные значения будут отображаться для данного продукта на всех страницах. Посмотрите страницу отдельного продукта (на которой вы кликали по реакциям) и страницу с их списком и наоборот, для всех страниц число реакций для конкретного продукта будет одинаковым.

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

Задание 1

Откройте ваше приложение со студентами. В файле studensSlice.js объектам для инициализации добавьте свойство votes с соответствующими полями. Сделайте это и для редьюсера studentAdded.

Задание 2

Внутри функции UserVotes в файле UserVotes.jsx заведите dispatch для хука useDispatch и сделайте отправку экшена voteClicked по клику на кнопки голосования, передайте ему id студента и название vote, подобно тому, как показано в уроке.

Задание 3

Выведите кнопочки для голосования в верстке для компонентов StudentsList и StudentPage.