React中Redux Action Hooks无法接收参数问题排查
问题分析与解决方案
你遇到的矛盾错误根源有两个:dispatch的调用方式错误,以及reducer内部的逻辑和写法问题,具体修正如下:
1. 修正dispatch的调用方式
你错误地将removeTodo()作为参数传给useAppDispatch,但useAppDispatch的作用是获取dispatch函数,正确的用法是先获取dispatch,再用它分发action:
import { useAppDispatch } from './app/store'; // 按你的实际路径导入 import { removeTodo, updateText, addTodo } from './features/todos/TodoSlice'; function YourComponent() { const dispatch = useAppDispatch(); // 先获取dispatch函数 // 正确调用方式:传入参数到action creator,再用dispatch分发 const handleRemoveTodo = (todoId: number) => { dispatch(removeTodo(todoId)); }; const handleUpdateText = (todoId: number, newText: string) => { dispatch(updateText({ id: todoId, newText })); }; // ...其他逻辑 }
之前的useAppDispatch(removeTodo())写法完全错误:useAppDispatch不需要参数,所以提示"Expected 0 but got 1";同时removeTodo需要传入number类型的payload,你调用时没传参数,所以又提示"Expected 1 but got 0",这就是矛盾错误的来源。
2. 修正Slice里的reducer逻辑与写法
你的reducer存在两个问题:
updateText的逻辑写反了:当前代码会更新不匹配id的todo文本,而不是匹配的那个- 多余的
state =赋值:Redux-Toolkit允许直接返回新状态,不需要赋值给state(虽然赋值表达式最终也会返回新状态,但写法冗余)
修正后的Slice代码:
import { createSlice } from '@reduxjs/toolkit' import type { PayloadAction } from '@reduxjs/toolkit' interface Todo { text: string; complete: boolean; id: number; } const initialState: Todo[] = [ { text: 'Walk the Dog', complete: false, id: 378 }, { text: 'Eat Dinner', complete: false, id: 912 } ] export const TodoSlice = createSlice({ name: 'todos', initialState, reducers: { // 直接返回过滤后的新数组,去掉多余的state= removeTodo: (state, action: PayloadAction<number>) => state.filter(todo => todo.id !== action.payload), // 修正逻辑:匹配id时返回更新后的todo,否则返回原todo updateText: (state, action: PayloadAction<{ id: number, newText: string }>) => state.map(todo => todo.id === action.payload.id ? { ...todo, text: action.payload.newText } : todo ), // 直接返回新数组,去掉多余的state= addTodo: (state, action: PayloadAction<Todo>) => [...state, action.payload] } }) export const { removeTodo, updateText, addTodo } = TodoSlice.actions export default TodoSlice.reducer
另外建议用严格相等运算符===代替==,避免隐式类型转换带来的潜在问题。
3. 确认Slice已注册到Store
最后检查你的根Store配置,确保已经将TodoReducer注册进去,比如:
// app/store.ts import { configureStore } from '@reduxjs/toolkit'; import todoReducer from '../features/todos/TodoSlice'; export const store = configureStore({ reducer: { todos: todoReducer, // 必须注册这一项 }, }); export type AppDispatch = typeof store.dispatch; export type RootState = ReturnType<typeof store.getState>;
如果这一步遗漏,也会导致action无法被正确处理,但你当前的错误主要来自前两点。
内容的提问来源于stack exchange,提问作者Razorshnegax018
相关产品推荐
相关产品推荐

