Подготовка данных для объекта 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, как показано в уроке. Запустите приложение и убедитесь, что все работает как и прежде.



Чат с GPT Компилятор