React-Redux与Redux Toolkit中Slice导入及使用报错求助
问题分析与修复方案
核心错误:Slice配置字段拼写错误
你的todoSlice中把reducers(复数)写成了reducer(单数),这是导致所有导入错误的根源。Redux Toolkit的createSlice要求定义reducer函数的字段是**reducers**,拼写错误会导致无法生成正确的action creators,进而出现你遇到的两种报错:
- 默认导入时,你拿到的是slice的reducer函数而非action creator,dispatch时自然会报
Cannot read properties of undefined (reading 'type') - 解构导入时,
todoSlice.actions未正确生成,addTodo是undefined,所以报addTodo is not a function
完整修复步骤
1. 修正Slice代码
import { createSlice } from "@reduxjs/toolkit"; const todoSlice = createSlice({ name: "todo", initialState: [ { id: 1, title: "Learn React", completed: true }, { id: 2, title: "Learn Redux", completed: false }, { id: 3, title: "Learn React-Redux", completed: false }, { id: 4, title: "Learn React-Router", completed: false } ], // 这里把reducer改成reducers(复数) reducers: { addTodo: (state, action) => { const newTodo = { id: Math.random(), title: action.payload.title, completed: false }; state.push(newTodo) }, deleteTodo: (state, action) => { // 修复:返回过滤后的新数组,RTK会自动处理状态更新 return state.filter((todo) => todo.id !== action.payload.id) } } }) export const { addTodo, deleteTodo } = todoSlice.actions; export default todoSlice.reducer
2. 修正Store中的拼写错误
把todoRedcuer改成todoReducer(规范拼写,避免后续隐患):
import { configureStore } from "@reduxjs/toolkit"; import todoReducer from './todoSlice' export const store = configureStore({ reducer: { todo: todoReducer } });
3. 修正组件代码
- 用解构方式导入
addTodo - 给
useState设置初始空字符串,避免输入框警告 - 变量名改为小写(符合JS命名规范)
import React from "react"; import { useDispatch } from "react-redux"; // 正确解构导入action creator import { addTodo } from "../redux/todoSlice"; const TodoForm = () => { // 初始值设为空字符串,变量名改为小写 const [todo, setTodo] = React.useState(''); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); // 空输入不提交 if (!todo.trim()) return; dispatch( addTodo({ title: todo, }) ); // 提交后清空输入框 setTodo(''); }; return ( <div className="flex items-center flex-col justify-center"> <h1 className="my-8">To-Do List</h1> <form onSubmit={handleSubmit}> <input type="text" name="todo" placeholder="Add todo..." value={todo} onChange={(e) => setTodo(e.target.value)} className="px-6 py-3 rounded-xl outline-0 bg-slate-100 mr-10" /> <button className="px-6 py-3 rounded-xl outline-0 bg-blue-500" > Add.. </button> </form> <h3>{todo}</h3> </div> ); }; export default TodoForm;
内容的提问来源于stack exchange,提问作者TheDejareDaniels
相关产品推荐
相关产品推荐

