Подготовка на данни за обекта 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, както е показано
в урока. Стартирайте приложението и се уверете,
че всичко работи както преди.