使用 createSlice 中的减速器从处于 redux 状态的数组中删除元素

Jel*_*ott 4 javascript reactjs react-redux redux-toolkit

我已经为此绞尽脑汁有一段时间了,任何帮助将不胜感激。

\n

我正在将 React 与 Redux Toolkit 结合使用,尽管 Redux 按预期响应,但我仍在努力让 React 从我的 UI 中删除“todo”。在 Redux 开发者工具中,removeTodo 按预期工作,从 todos 数组状态中删除一个待办事项,但 React 不会跟随,因此我的 UI 不会随之改变。我的 addTodo 操作在 React 和 Redux 中都按预期工作。

\n

当我单击调用removeTodo 调度的按钮时,我当前的代码出现以下错误。

\n
TypeError: Cannot read property 'length' of undefined\nApp\nC:/Users/joeee/Documents/redux-middleware/src/app/App.js:13\n  10 | \n  11 |  return (\n  12 |    <div style={divStyles}>\n> 13 |      <TodosForm />\n     | ^  14 |      {todos.length > 0 && <TodoList />}\n  15 |    </div>\n  16 |  )\nView compiled\n\xe2\x96\xb6 19 stack frames were collapsed.\n
Run Code Online (Sandbox Code Playgroud)\n

应该注意的是,当我的待办事项数组状态的长度 > 0 时,我仅在 TodoList 组件中渲染,因为我不希望在没有待办事项时渲染该组件。我是 React 和 Redux 的新手,可能有一个非常简单的解决方案,但据我所知,当调用 removeTodo 时,todos 数组状态将被完全删除,而不是仅返回 id 不等于传入的 id 的状态这就是为什么我认为我收到的错误告诉我它无法读取未定义的.length,因为我的待办事项状态现在为空。

\n

我删除了 todos.length 需要大于 0 才能渲染 TodoList 的要求,但随后出现错误,它无法读取 TodoList 中未定义的 .map (我的待办事项状态),这对我来说强化了我的整个待办事项状态似乎正在被删除。

\n

这是我的 todosSlice:

\n
import { createSlice } from '@reduxjs/toolkit';\n\nexport const todosSlice = createSlice({\n  name: 'todos',\n  initialState: {\n    todos: [],\n  },\n  reducers: {\n    addTodo: (state, action) => {\n      const { id, task } = action.payload; \n\n      state.todos.push({ id, task })\n    },\n    removeTodo: (state, action) => {\n      // console.log(state.todos);\n\n      const { id } = action.payload; \n      // console.log(id);\n      \n      return state.todos.filter(item => item.id !== id);\n      \n    }\n  },\n});\n\nexport const selectTodos = state => state.todos.todos; \n\nexport const { addTodo, removeTodo } = todosSlice.actions; \nexport default todosSlice.reducer; \n
Run Code Online (Sandbox Code Playgroud)\n

应用程序.js:

\n
import React from 'react';\nimport { useSelector } from 'react-redux'; \nimport TodosForm from '../components/TodosForm';\nimport TodoList from '../components/TodoList';\nimport { selectTodos } from '../features/todosSlice';\n\nexport const App = () => {\n  const todos = useSelector(selectTodos);\n  // console.log(todos.length);\n\n  return (\n    <div style={divStyles}>\n      <TodosForm />\n      {todos.length > 0 && <TodoList />}\n    </div>\n  )\n}\n\nexport default App;\n
Run Code Online (Sandbox Code Playgroud)\n

TodoList.js

\n
import React from 'react';\nimport { useSelector } from 'react-redux';\nimport { selectTodos } from '../features/todosSlice';\nimport Todos from './Todos';\n\nconst TodoList = () => {\n\n  const todos = useSelector(selectTodos);\n  // console.log(todos);\n\n  return (\n    <div style={divStyles}>\n      <h3 style={headerStyles}>Your Todos: </h3>\n      \n      {todos.map(todo => <Todos key={todo.id} task={todo.task} id={todo.id} />)}\n    </div>\n  )\n}\n\nexport default TodoList\n
Run Code Online (Sandbox Code Playgroud)\n

Todos.js

\n
import React from 'react';\nimport { useDispatch } from 'react-redux'; \nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faTrashAlt } from '@fortawesome/free-solid-svg-icons'\nimport { faEdit } from '@fortawesome/free-solid-svg-icons'\nimport { removeTodo } from '../features/todosSlice';\n\nconst Todos = ({ task, id }) => {\n  const dispatch = useDispatch();\n\n  const handleDeleteClick = () => {\n    dispatch(removeTodo({id: id}));\n  }\n\n  return (\n    <div style={divStyles}>\n      <li style={listStyles}>{task}</li>\n      <div>\n        <button className="faEditIcon" style={btnStyles}><FontAwesomeIcon icon={faEdit}/></button>\n        <button className="faDeleteIcon" style={btnStyles} onClick={handleDeleteClick}><FontAwesomeIcon icon={faTrashAlt}/></button>\n      </div>\n    </div>\n  )\n}\n\nexport default Todos;\n
Run Code Online (Sandbox Code Playgroud)\n

还有我的 store.js

\n
import { configureStore } from '@reduxjs/toolkit'; \nimport todosSliceReducer from '../features/todosSlice'; \n\nexport default configureStore({\n  reducer: {\n    todos: todosSliceReducer,\n  },\n});\n
Run Code Online (Sandbox Code Playgroud)\n

Ani*_*ony 5

您可以按如下方式更新removeTodo并查看吗?

removeTodo: (state, action) => {
      // console.log(state.todos);

      const { id } = action.payload; 
      // console.log(id);
      
state.todos = state.todos.filter(item => item.id !== id)
      
    }
Run Code Online (Sandbox Code Playgroud)