简体   繁体   English

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

[英]Delete element from array in redux state using a reducer in createSlice

I've been scratching my brain for a while now with this one and any help would be appreciated.我已经用这个抓挠我的大脑一段时间了,任何帮助将不胜感激。

I am using React with Redux Toolkit and I'm struggling to get React to remove a 'todo' from my UI even though Redux is responding as expected.我正在将 React 与 Redux Toolkit 一起使用,即使 Redux 按预期响应,我也很难让 React 从我的 UI 中删除“待办事项”。 In Redux Developer Tools removeTodo works as expected, removing a todo from the todos array state, but React doesn't follow and therefore my UI doesn't change with it.在 Redux Developer Tools 中,removeTodo 按预期工作,从 todos 数组状态中删除了一个待办事项,但 React 不遵循,因此我的 UI 不会随之改变。 My addTodo action works as expected in both React and Redux.我的 addTodo 操作在 React 和 Redux 中都按预期工作。

My current code provides me with the following error when I click the button that calls the dispatch of removeTodo.当我单击调用 removeTodo 调度的按钮时,我当前的代码为我提供了以下错误。

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.

It should be noted that I am only rendering in my TodoList component when my todos array state has a length > 0 as I don't want the component rendered in when there are no todos.应该注意的是,当我的 todos 数组状态的长度 > 0 时,我只在我的 TodoList 组件中渲染,因为我不希望在没有 todos 时渲染组件。 I am new to React and Redux and there is probably a very simple solution but from what I can decipher is that when removeTodo is called, the todos array state is being removed completely rather than just returning those with id's not equal to the id passed in. This is why I assume the error I am getting is telling me it can't read the .length of undefined because my todos state is now empty.我是 React 和 Redux 的新手,可能有一个非常简单的解决方案,但据我所知,当 removeTodo 被调用时,todos 数组状态将被完全删除,而不是仅仅返回那些 id 不等于传入的 id 的状态. 这就是为什么我假设我得到的错误是告诉我它无法读取 undefined 的 .length 因为我的 todos 状态现在是空的。

I removed the requirement for the todos.length needing to be greater than 0 for TodoList to render but then I got the error that it couldn't read .map of undefined (my todos state) in TodoList which to me reinforces that my whole todos state seems to be being deleted.我删除了 todos.length 需要大于 0 才能呈现 TodoList 的要求,但后来我得到了它无法读取 TodoList 中未定义(我的待办事项状态)的 .map 的错误,这对我来说加强了我的整个待办事项状态似乎正在被删除。

Here is my todosSlice:这是我的 todosSlice:

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:应用程序.js:

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 TodoList.js

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 Todos.js

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;

And my store.js还有我的 store.js

import { configureStore } from '@reduxjs/toolkit'; 
import todosSliceReducer from '../features/todosSlice'; 

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

Can you update removeTodo as below and see.您可以按如下方式更新 removeTodo 并查看。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM