Przygotowanie danych dla obiektu action w Redux
Niedawno rozmawialiśmy o tym, że
funkcja createSlice oczekuje jednego
argumentu przy tworzeniu action.payload.
Z jednej strony upraszcza to jej użycie,
z drugiej zaś może wymagać dodatkowych
działań w celu przygotowania zawartości
obiektu action.
Otwórzmy naszą aplikację z
produktami, a w niej plik NewProductForm.jsx.
Zwróć uwagę na następującą linię kodu:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
Tutaj zbieramy obiekt payload
bezpośrednio w komponencie React i przekazujemy go do
akcji productAdded. A co, jeśli będziemy
musieli wysyłać taką samą akcję z
kilku komponentów lub logika do
zbudowania okaże się skomplikowana? W zasadzie naszemu
komponentowi powinno być wszystko jedno, jak
wygląda obiekt w payload dla danej
akcji. Poza tym nie odpowiada nam
ciągłe powielanie kodu.
Te problemy znów może nam pomóc
rozwiązać nasz słynny createSlice,
ponieważ przy pisaniu reducera
pozwala nam on na użycie funkcji callback
prepare, w której można pisać różną
logikę, generować liczby losowe i tak dalej. W
takim przypadku wartość dla pola reducera może
być przedstawiona w postaci następującego obiektu:
{reducer, prepare}
Otwórzmy nasz plik productsSlice.js
i zmieńmy kod dla reducera productAdded.
Teraz ten fragment kodu:
productAdded(state, action) {
state.push(action.payload)
},
Zamienimy na następujący, w którym
funkcja reducer będzie zajmować się
aktualizacją stanu w store, a prepare -
zwracać obiekt payload z
wygenerowanym id i innymi naszymi
danych:
productAdded: {
reducer(state, action) {
state.push(action.payload)
},
prepare(name, desc, price, amount) {
return {
payload: {
id: nanoid(),
name,
desc,
price,
amount,
},
}
},
},
Ponieważ teraz będziemy generować id tutaj, a nie w komponencie, dodajmy nanoid do importu:
import { createSlice, nanoid } from '@reduxjs/toolkit'
Na koniec wprowadźmy zmiany w
NewProductForm.jsx. Zamiast
linii:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
Będziemy mieli taką, w której po prostu
przez przecinek przekażemy potrzebne nam
dane (nie zapomnij w tym pliku usunąć
nanoid z importu):
dispatch(productAdded(name, desc, price, amount))
Uruchommy aplikację, następnie utwórzmy nowy produkt i upewnijmy się, że niczego nie zepsuliśmy.
Otwórz swoją aplikację ze studentami.
W pliku StudentsSlice.js przepisz
swój reducer studentAdded w taki sposób,
aby był w postaci obiektu {reducer, prepare},
jak pokazano w lekcji.
Wprowadź odpowiednie zmiany w
pliku NewStudentForm.jsx, jak pokazano
w lekcji. Uruchom aplikację i upewnij się,
że wszystko działa tak jak poprzednio.