Подготовка данных для объекта action в Redux
Недавно мы говорили с вами о том, что
функция createSlice
ожидает один
аргумент при создании action.payload
.
С одной стороны это упрощает ее использование,
с другой же может потребовать дополнительных
движений для подготовки содержимого
объекта action.
Давайте откроем наше приложение с
продуктами, а в нем файл NewProductForm.jsx
.
Обратите внимание на следующую строчку кода:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
Здесь мы собираем payload
объект
прямо в React компоненте и передаем его в
экшен productAdded
. А что если нам
придется отправлять такой же экшен из
нескольких компонентов или логика для
сборки окажется сложной? По идее нашему
компоненту должно быть все равно как
выглядит объект в payload
для данного
action. К тому же нас не устраивает
постоянное дублирование кода.
Эти проблемы нам снова может помочь
решить наш знаменитый createSlice
,
поскольку при написании редьюсера он
позволяет нам использовать callback-функцию
prepare
, в которой можно писать различную
логику, генерировать случайные числа и прочее. В
таком случае значение для поля редьюсера может
быть представлено в виде следующего объекта:
{reducer, prepare}
Давайте откроем наш файл productsSlice.js
и изменим код для редьюсера productAdded
.
Теперь этот кусочек кода:
productAdded(state, action) {
state.push(action.payload)
},
Мы поменяем на следующий, в котором
функция reducer
будет заниматься
обновлением стейта в store, а prepare
-
возвращать объект payload
со
сгенерированным id и другими нашими
данными:
productAdded: {
reducer(state, action) {
state.push(action.payload)
},
prepare(name, desc, price, amount) {
return {
payload: {
id: nanoid(),
name,
desc,
price,
amount,
},
}
},
},
Так как теперь мы будем генерировать id здесь, а не в компоненте, давайте добавим nanoid в импорт:
import { createSlice, nanoid } from '@reduxjs/toolkit'
Напоследок внесем изменения в
NewProductForm.jsx
. Вместо
строчки:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
У нас будет такая, в которой мы просто
через запятую передадим необходимые нам
данные (не забудьте в этом файле убрать
nanoid из импорта):
dispatch(productAdded(name, desc, price, amount))
Запустим приложение, затем создадим новый продукт и убедимся, что мы ничего не поломали.
Откройте ваше приложение со студентами.
В файле StudentsSlice.js
перепишите
ваш редьюсер studentAdded
таким образом,
чтобы он был в виде объекта {reducer, prepare}
,
как показано в уроке.
Внесите соответствующие изменения в
файл NewStudentForm.jsx
, как показано
в уроке. Запустите приложение и убедитесь,
что все работает как и прежде.