Preparing data for the action object in Redux
Recently we talked about the fact that the createSlice
function expects one argument when creating action.payload
. On the one hand, this simplifies its use, on the other hand, it may require additional steps to prepare the contents of the action object.
Let's open our product app, and in it the file NewProductForm.jsx
. Pay attention to the following line of code:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
Here we are assembling the payload
object directly in the React component and passing it to the productAdded
action. But what if we have to send the same action from several components or the logic for assembling is complex? Ideally, our component should not care what the object looks like in payload
for a given action. In addition, we are not happy with the constant duplication of code.
Our famous createSlice
can help us solve these problems again, because when writing a reducer it allows us to use the prepare
callback function, in which we can write various logic, generate random numbers, etc. In this case, the value for the reducer field can be represented as the following object:
{reducer, prepare}
Let's open our productsSlice.js
file and change the code for the productAdded
reducer. This piece of code is now:
productAdded(state, action) {
state.push(action.payload)
},
We will change it to the following, in which the reducer
function will be responsible for updating the state in the store, and prepare
will return the payload
object with the generated id and our other data:
productAdded: {
reducer(state, action) {
state.push(action.payload)
},
prepare(name, desc, price, amount) {
return {
payload: {
id: nanoid(),
name,
desc,
price,
amount,
},
}
},
},
Since we'll now be generating the id here instead of in the component, let's add nanoid to the import:
import { createSlice, nanoid } from '@reduxjs/toolkit'
Finally, let's make changes to NewProductForm.jsx
. Instead of the line:
dispatch(productAdded({
id: nanoid(), name, desc, price, amount
}))
We will have one in which we will simply pass the data we need through commas (don't forget to remove nanoid
from the import in this file):
dispatch(productAdded(name, desc, price, amount))
Let's run the application, then create a new product and make sure we haven't broken anything.
Open your students app. In StudentsSlice.js
, rewrite your studentAdded
reducer so that it is an {reducer, prepare}
object, as shown in the tutorial.
Make the appropriate changes to the NewStudentForm.jsx
file as shown in the tutorial. Run the application and make sure everything works as before.