首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用createSlice中的reducer从处于redux状态的数组中删除元素

使用createSlice中的reducer从处于redux状态的数组中删除元素
EN

Stack Overflow用户
提问于 2021-07-07 18:43:13
回答 1查看 561关注 0票数 1

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

我正在使用React和Redux Toolkit,我正在努力让React从我的UI中删除一个'todo‘,尽管Redux的响应与预期一致。在Redux开发人员工具中,removeTodo按预期工作,从待办事项数组状态中删除待办事项,但React不会跟随,因此我的UI也不会随之改变。我的addTodo操作在React和Redux中都能正常工作。

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

代码语言:javascript
复制
TypeError: Cannot read property 'length' of undefined
App
C:/Users/joeee/Documents/redux-middleware/src/app/App.js:13
  10 | 
  11 |  return (
  12 |    <div style={divStyles}>
> 13 |      <TodosForm />
     | ^  14 |      {todos.length > 0 && <TodoList />}
  15 |    </div>
  16 |  )
View compiled
▶ 19 stack frames were collapsed.

需要注意的是,只有当todos数组状态的长度大于0时,我才会在TodoList组件中呈现,因为我不希望在没有todo时呈现该组件。我是React和Redux的新手,可能有一个非常简单的解决方案,但从我能破解的是,当调用removeTodo时,todos数组状态将被完全移除,而不是返回id不等于传入的id的那些。这就是为什么我假设我得到的错误告诉我它不能读取未定义的.length,因为我的待办事项状态现在是空的。

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

这是我的todosSlice:

代码语言:javascript
复制
import { createSlice } from '@reduxjs/toolkit';

export const todosSlice = createSlice({
  name: 'todos',
  initialState: {
    todos: [],
  },
  reducers: {
    addTodo: (state, action) => {
      const { id, task } = action.payload; 

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

      const { id } = action.payload; 
      // console.log(id);
      
      return state.todos.filter(item => item.id !== id);
      
    }
  },
});

export const selectTodos = state => state.todos.todos; 

export const { addTodo, removeTodo } = todosSlice.actions; 
export default todosSlice.reducer; 

App.js:

代码语言:javascript
复制
import React from 'react';
import { useSelector } from 'react-redux'; 
import TodosForm from '../components/TodosForm';
import TodoList from '../components/TodoList';
import { selectTodos } from '../features/todosSlice';

export const App = () => {
  const todos = useSelector(selectTodos);
  // console.log(todos.length);

  return (
    <div style={divStyles}>
      <TodosForm />
      {todos.length > 0 && <TodoList />}
    </div>
  )
}

export default App;

TodoList.js

代码语言:javascript
复制
import React from 'react';
import { useSelector } from 'react-redux';
import { selectTodos } from '../features/todosSlice';
import Todos from './Todos';

const TodoList = () => {

  const todos = useSelector(selectTodos);
  // console.log(todos);

  return (
    <div style={divStyles}>
      <h3 style={headerStyles}>Your Todos: </h3>
      
      {todos.map(todo => <Todos key={todo.id} task={todo.task} id={todo.id} />)}
    </div>
  )
}

export default TodoList

Todos.js

代码语言:javascript
复制
import React from 'react';
import { useDispatch } from 'react-redux'; 
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons'
import { faEdit } from '@fortawesome/free-solid-svg-icons'
import { removeTodo } from '../features/todosSlice';

const Todos = ({ task, id }) => {
  const dispatch = useDispatch();

  const handleDeleteClick = () => {
    dispatch(removeTodo({id: id}));
  }

  return (
    <div style={divStyles}>
      <li style={listStyles}>{task}</li>
      <div>
        <button className="faEditIcon" style={btnStyles}><FontAwesomeIcon icon={faEdit}/></button>
        <button className="faDeleteIcon" style={btnStyles} onClick={handleDeleteClick}><FontAwesomeIcon icon={faTrashAlt}/></button>
      </div>
    </div>
  )
}

export default Todos;

还有我的store.js

代码语言:javascript
复制
import { configureStore } from '@reduxjs/toolkit'; 
import todosSliceReducer from '../features/todosSlice'; 

export default configureStore({
  reducer: {
    todos: todosSliceReducer,
  },
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-07-07 18:57:43

你能像下面这样更新removeTodo并查看吗?

代码语言:javascript
复制
removeTodo: (state, action) => {
      // console.log(state.todos);

      const { id } = action.payload; 
      // console.log(id);
      
state.todos = state.todos.filter(item => item.id !== id)
      
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68284530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档