redux useDispatch出现错误,无法添加到数组中

0qx6xfy6  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(111)

为了尝试理解Redux,我设置了一个简单的todo项目。很遗憾,我无法让useDispatch工作。
我可以得到所有我用useSelect存储的todo,但是我不能添加todo,因为我认为useDispatch导致了一个错误。
错误说:“e.preventDefault()不是一个函数”,但是当我删除useDispatch时,它没有显示这个错误,所以我认为错误来自useDispatch
下面是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) => {
      state.list = action.payload;
    },
  },
});

export const { addTodo } = slice.actions;

export default slice.reducer;

字符串
下面是表单组件:

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();

  const addTodo = (e, addTodo) => {
    e.preventDefault();
    dispatch(addTodo([...list, { id: list.length + 1, label: todo }]));

    setTodo("");
  };

  return (
    <div>
      <FormWrapper>
        <form action="" onSubmit={(e) => addTodo(e, addTodo)}>
          <input
            type="text"
            name="todo"
            id="todo"
            value={todo}
            onChange={(e) => setTodo(e.target.value)}
          />
          <input type="submit" value="Add todo" />
        </form>
      </FormWrapper>
    </div>
  );
}


这是我设置的商店。我确实将它 Package 在了我的应用组件上:

import { configureStore } from "@reduxjs/toolkit";
import listReducer from "../slices/todoSlice";

// config the store
const store = configureStore({
  reducer: {
    list: listReducer,
  },
});

// export default the store
export default store;

ztmd8pv5

ztmd8pv51#

代码没有分派您认为的addTodo。不是将导入的addTodo操作传递给本地addTodo提交处理程序函数,而是将本地addTodo提交处理程序传递给其自身并在dispatch中调用,并且随后的调用传递了一个参数,该参数不是要调用preventDefault的事件对象。

...
import { addTodo } from "./list.slice"; // <-- never referenced

function Form() {
  const list = useSelector((state) => state.list.value);
  const [todo, setTodo] = useState("");

  const dispatch = useDispatch();

  const addTodo = (e, addTodo) => { // <-- (1) this addTodo is in scope
    e.preventDefault();
    dispatch(addTodo( // <-- (3) calls local addTodo without event object!
      [...list, { id: list.length + 1, label: todo }]
    ));

    setTodo("");
  };

  return (
    <div>
      <FormWrapper>
        <form action="" onSubmit={(e) => addTodo(e, addTodo)}> // <-- (2) addTodo passed to itself!
          <input
            type="text"
            name="todo"
            id="todo"
            value={todo}
            onChange={(e) => setTodo(e.target.value)}
          />
          <input type="submit" value="Add todo" />
        </form>
      </FormWrapper>
    </div>
  );
}

字符串
修复是微不足道的,将提交处理程序重命名为 anything,但与您想要分派的操作的标识符相同。由于addTodo操作已经具有文件作用域,因此您也不需要通过提交处理程序回调的参数传递操作。

...
import { addTodo } from "./list.slice";

function Form() {
  const list = useSelector((state) => state.list.value);
  const [todo, setTodo] = useState("");

  const dispatch = useDispatch();

  const submitHandler = (e) => {
    e.preventDefault();
    dispatch(addTodo( // <-- imported addTodo action :)
      [...list, { id: list.length + 1, label: todo }]
    ));

    setTodo("");
  };

  return (
    <div>
      <FormWrapper>
        <form action="" onSubmit={submitHandler}>
          <input
            type="text"
            name="todo"
            id="todo"
            value={todo}
            onChange={(e) => setTodo(e.target.value)}
          />
          <input type="submit" value="Add todo" />
        </form>
      </FormWrapper>
    </div>
  );
}

相关问题