Reputation: 341
I'm having some trouble with the prepare
callback function included in my addEntity
reducer I include in redux-toolkit's createSlice
function.
I'm trying to use the prepare
callback to add unique IDs to my action payloads.
The redux-toolkit createSlice
documentation says:
If you need to customize the creation of the payload value of an action creator by means of a prepare callback, the value of the appropriate field of the reducers argument object should be an object instead of a function. This object must contain two properties: reducer and prepare. The value of the reducer field should be the case reducer function while the value of the prepare field should be the prepare callback function.
Here is the code I am using (written w/ TypeScript):
import { createSlice, createEntityAdapter } from '@reduxjs/toolkit';
import { MyEntityType } from '../../js/types/MyEntityType';
import { v4 as uuidv4 } from 'uuid';
const myEntityAdapter = createEntityAdapter<MyEntityType>();
const { reducer, actions } = createSlice({
name: 'myEntity',
initialState: myEntityAdapter.getInitialState(),
reducers: {
addEntity: {
reducer: myEntityAdapter.addOne,
prepare: (payload) => ({...payload, id: uuidv4()}),
},
removeEntity: myEntityAdapter.removeOne,
updateEntity: myEntityAdapter.updateOne,
}
});
When I compile my app and test creating an entity using the addEntity
action, however, the prepare
callback doesn't appear to do anything.
Here is the action I dispatch using Redux DevTools:
{
type: 'myEntity/addEntity',
payload: {myPayloadTrait: 100, id: 'test'} // Expected behavior: this id should be overwritten in the prepare callback
}
Resulting state:
myEntity: {
ids: {
0:"test"
},
entities: {
"test": {
myPayloadTrait: 100
id: "test"
}
}
}
Why doesn't my prepare callback overwrite the "test"
id before the payload is passed to the reducer? Any help or guidance would be much appreciated.
Upvotes: 1
Views: 1619
Reputation: 67567
The prepare callback must return an object that looks like {payload?, meta?, error?}
. Your code is currently returning the intended payload directly.
Change it to:
addEntity: {
reducer: myEntityAdapter.addOne,
prepare: (payload) => ({
payload: {
...payload,
id: uuidv4()
}
}),
}
Upvotes: 2