Skip to content
Advertisement

I am learning Redux thunk by using createAsynThunk. I try to delete an item in todoState but it doesn’t work and i don’t know the reason

My slices file filename: slices.ts

import { createSlice, PayloadAction, configureStore, Middleware, createAsyncThunk } from "@reduxjs/toolkit"; import { combineReducers } from "redux"; import { Todo } from "./Todo";

const myMiddleware: Middleware<{}, unknown> = ({ dispatch }) => next => action => { if (action.type === 'todo/addTodo' && action.payload.title.includes("fuck")) { action.payload.title = action.payload.title.replace("fuck", "love"); return dispatch(action); } return next(action); }

const wait = (ms: number): Promise => { return new Promise(resolve => setTimeout(resolve, ms)); }

export const deleteTodo = createAsyncThunk("todo/deleteTodo", async (id: number) => { await wait(1000); return id; })

const initialState: Todo[] = [] const todoSlice = createSlice({ name: 'todo', initialState, reducers: { addTodo: (state, action: PayloadAction) => { state.push(action.payload) }, }, extraReducers: (builder) => { builder.addCase(deleteTodo.fulfilled, (state, action) => { const newState = state.filter(todo => todo.id !== action.payload); return newState; } ) } })

const rootReducer = combineReducers({ todoReducer: todoSlice.reducer })

export const store = configureStore({ reducer: rootReducer, middleware: defaultMiddleware => defaultMiddleware().concat(myMiddleware) })

My action creators. filename: actioncreators.ts

import { createAction, createAsyncThunk, Dispatch } from "@reduxjs/toolkit"; import { Todo } from "./Todo";

export const addTodo = createAction('todo/addTodo', (todo: Todo) => { return { payload: todo } })

Todo interface, filename: Todo.ts

export interface Todo { id: number, title: string, completed: boolean }

I run my index file, filename: index.ts

import { store } from "./slices"; import { Todo } from "./Todo"; import { deleteTodo } from "./slices";

const todo1: Todo = { id: 1, title: "Do homework", completed: true }

const todo2: Todo = { id: 2, title: "Wake up", completed: true }

store.dispatch({ type: 'todo/addTodo', payload: todo1 }) store.dispatch({ type: 'todo/addTodo', payload: todo2 }) store.dispatch(deleteTodo(1)) console.log(store.getState().todoReducer)

I expect it would be

[ id: 2, title: 'Wake up', completed: true } ]

But actually it is.

[ id: 1, title: 'Do homework', completed: true }, id: 2, title: 'Wake up', completed: true } ]

Advertisement

Answer

Your code is fine. The reason you are getting the same result after delete is because you have wait in your delete handler. In the mean time, when wait is going on, your next statement executes (concept of call stack & task queue) which give the same result.

To validate this, add wait for the second console.log and you’ll see the updated results.

Following is the link to the stackblitz template having your code: stackblitz

console.log result

Read more about JavaScript’s Task queue & call stack call stack & event look

Hope that answers your doubts.

Thanks, Manish

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement