使用useDispatch报错,无法向数组添加Todo项
问题分析与解决方案
核心问题1:函数重名引发作用域冲突
你在Form组件里导入了Redux的addTodo action,又在组件内部定义了同名的addTodo函数,直接覆盖了导入的action。表单提交时调用的addTodo是你自己定义的函数,而非Redux的action creator,这不仅导致dispatch调用了错误的函数,还打乱了参数传递逻辑,最终引发e.preventDefault()的异常。
核心问题2:Slice中reducer的状态字段错误
你的initialState用value字段存储todo列表,但reducer里却赋值给state.list,这会导致Redux状态更新后,useSelector依然读取不到新的列表数据。
其他小问题
- Form组件未导入
useState,会触发React钩子未定义的错误; - 用
list.length + 1生成id存在重复风险(比如删除项后再添加),建议用Date.now()这类唯一值替代。
修正后的代码
1. Todo Slice 修正
import { createSlice } from "@reduxjs/toolkit"; const slice = createSlice({ name: "list", initialState: { value: [ { id: 0, label: "Boodschappen" }, { id: 1, label: "Scheren" }, { id: 2, label: "Stoep vegen" }, ], }, reducers: { addTodo: (state, action) => { // 修正为更新value字段,与initialState结构匹配 state.value = action.payload; }, }, }); export const { addTodo } = slice.actions; export default slice.reducer;
2. Form组件修正
import { useState } from 'react'; // 新增导入useState import { useDispatch, useSelector } from "react-redux"; import { addTodo } from "../../slices/todoSlice"; function Form() { const list = useSelector((state) => state.list.value); const [todo, setTodo] = useState(""); const dispatch = useDispatch(); // 改名避免和导入的action重名 const handleAddTodo = (e) => { e.preventDefault(); // 直接使用导入的addTodo action dispatch(addTodo([ ...list, { id: Date.now(), label: todo } // 用时间戳生成唯一id ])); setTodo(""); }; return ( <div> <FormWrapper> {/* 直接绑定处理函数,无需额外传参 */} <form onSubmit={handleAddTodo}> <input type="text" name="todo" id="todo" value={todo} onChange={(e) => setTodo(e.target.value)} /> <input type="submit" value="Add todo" /> </form> </FormWrapper> </div> ); }
3. Store配置无需修改
你的Store配置逻辑正确,保持原样即可。
内容的提问来源于stack exchange,提问作者Sjoerd Vermeijden
相关产品推荐
相关产品推荐

