I get an error for second builder and it says: Uncaught TypeError: typeOrActionCreator is undefined.
I don't know what's wrong with that builder. And when I remove that builder, it errors about next builder. (Note I dispatch my thunkFunction from last builder)
export const updateSelectedOrNewMovementData = ("myMovements/updateSelectedOrNewMovementData", async(allData) => {
const {data, type, motion_id} = allData
try{
const {receivedData} = await patchRequest(`/coach/motion/${motion_id}`, data)
return type
}
catch (err) {
console.error("err", err.response.data.message);
}
})
...here there are codes for my slice.
extraReducers(builder) {
builder
.addCase(handleGetMyMovements.fulfilled, (state, action) => {
const data = action.payload;
if (data?.length > 0) {
state.myMovements = [...state.myMovements, ...data];
state.myMovementsTemp = [...state.myMovements, ...data];
}
if (data?.length >= 20) {
state.status.isNotMoreData = true;
} else {
state.status.isNotMoreData = false;
}
state.status.myMovementsLoading = false;
})
.addCase(handleGetMyMovements.pending, (state, action) => {
state.status.myMovementsLoading = true;
});
builder
.addCase(updateSelectedOrNewMovementData.fulfilled, (state, action) => {
if (action?.payload === "formData") {
state.status.selectedOrNewMovementLoading = "sentData"
setTimeout(() => {
state.status.selectedOrNewMovementLoading = false
window.history.back();
}, 3000);
}
})
.addCase(updateSelectedOrNewMovementData.pending, (state, action) => {
if (action?.payload === "formData") {
state.status.selectedOrNewMovementLoading = true
}
})
.addCase(updateSelectedOrNewMovementData.rejected, (state, action) => {
state.status.selectedOrNewMovementLoading = "error"
});
builder
.addCase(createNewMovement.fulfilled, (state, action) => {
const payload = action?.payload
const dispatch = payload?.dispatch
state.status.selectedOrNewMovementLoading = false
if (payload?.data?.is_successful) {
state.motionId = payload?.data?.motion_id
dispatch(updateSelectedOrNewMovement({
data: payload?.myForm,
type: "formData",
motion_id: payload?.data?.motion_id
}))
dispatch(updateSelectedOrNewMovement({
data: payload?.textFormBody,
type: "rawData",
motion_id: payload?.data?.motion_id
}))
}
})
.addCase(createNewMovement.pending, (state, action) => {
state.status.selectedOrNewMovementLoading = true
})
.addCase(createNewMovement.rejected, (state, action) => {
state.status.selectedOrNewMovementLoading = "error"
})
},
You are not allowed in Redux, ever, to dispatch from inside a reducer. The same goes for asynchronous logic like doing a setTimeout
.
Reducer logic has to be a pure synchronous function without side effects.
You might want to do the logic you are currently doing in a thunk or with the listener middleware instead.
All that said, the problem you are incountering is because one of the actions you are passing to one of your .addCase
calls seems to be undefined
.
That's probably caused by your updateSelectedOrNewMovementData
being a normal function. It's not an async thunk, so it has no pending
, fulfilled
or rejected
properties. You have to use createAsyncThunk
for that.
- export const updateSelectedOrNewMovementData = ("myMovements/updateSelectedOrNewMovementData", async(allData) => {
+ export const updateSelectedOrNewMovementData = createAsyncThunk("myMovements/updateSelectedOrNewMovementData", async(allData) => {
Frankly, a lot of this code looks kinda right, but then is making a lot of tiny errors that show that your are missing some important basics.
I would recommend that you go through the Redux Essentials tutorial and following these to get a good grasp of the Redux data flow.