javascript 从对象数组{}中删除对象

lnlaulya  于 2023-02-15  发布在  Java
关注(0)|答案(1)|浏览(65)

我正在尝试为任务生成“待办事项”列表。初始状态必须具有代码中显示的结构。我是编码新手,不知道如何从对象数组中删除对象。
我试过使用.pop()和.筛选器()方法,但它们不被接受,因为对象数组是对象的对象,而不是实际数组。我还尝试查找索引并删除state.data[index],但控制台发送错误消息“在呈现其他组件时无法更新组件”。当我不包括handleDeleteClick时,其余代码工作正常()函数并移除deleteItem还原器,代码如下:

//the following creates an item component for each item in the 'to do' list

import React, {useState} from 'react';
import { useDispatch } from 'react-redux';
import { editItem, deleteItem, completedItem } from '../store/todoSlice';


const TodoItem = ({ id, content, completed }) => {
 const dispatch = useDispatch();

//initialising state for items that the user wants to edit
const [edit, setEdit] = useState(false);
const [newItem, setNewItem] = useState(content);
const [finishedItem, setFinishedItem]= useState(false);

//function to call deleteItem reducer
 const handleDeleteClick = () => {
    dispatch(deleteItem({id, content}))
}

//function to call editItem reducer
 const onSubmit = (event) => {
    event.preventDefault();
    dispatch(
        editItem({id, newItem, completed}));
    
    //setting edit and finished state back to null
    setNewItem("");
    setEdit(false);
    setFinishedItem(false);
};

//function to call completedItem reducer
const completedTask = (event) => {
    event.preventDefault();
    dispatch(
        completedItem({id, content, completed})
    );
    setFinishedItem(true);
};

//if edit state is true, return <input> element to edit the item requested
if(edit){
    return (
        <form>
            <input id="editInput" value={newItem} onChange= {(e) => setNewItem(e.target.value)} placeholder="Edit your item"/>
            <button onClick = {onSubmit} type='submit' id="submitButton">ADD</button>
        </form>
        
    )
}

//if edit state is false and finishedItem is true, return same list and add an id to completed button
if(!edit && finishedItem) {
    return(
        <div id="itemSection">
        
        <li id="item">{content} 
            <button onClick= {handleDeleteClick(content)} className="function">DELETE</button>
            <button onClick={() => setEdit(true)} className="function"> EDIT</button>
            <button onClick={completedTask} id="completed">COMPLETED</button>
        
        </li>
    </div>

    )
}

//else, return <ul> element for each 'todo' item with 3 buttons to edit, delete or complete task 
return (
    <div id="itemSection">
        
        <li id="item">{content} 
            <button onClick={handleDeleteClick()} className="function">DELETE</button>
            <button onClick={() => setEdit(true)} className="function"> EDIT</button>
            <button onClick={completedTask}>COMPLETED</button>
        
        </li>
    </div>
);
};

export default TodoItem;

//the following creates state slice for the todos object array

import { createSlice } from "@reduxjs/toolkit";

export const toDoSlice = createSlice({
name: "todos",

//set initial state of object array
initialState: {
    nextId: 2,
    data:
    {
        1: {
            content: 'Content 1',
            completed: false
        }
    }
   
},

reducers: {
    //function to add item to object array
    addItem: (state, action) => {
        state.data = 
            {
                ...state.data,
                [state.nextId]: {
                    content: action.payload.content,
                    completed: false
                }
            }
        state.nextId += 1;
        
    },

    //function to delete item from object array
    deleteItem: (state, action) => {
            const index= action.payload.id;
            delete state.data[index];
    
    },
        

    //function to edit item from object array
    editItem: (state, action) => {
       state.data =
       {
        ...state.data,
        [action.payload.id]: {
            content: action.payload.newItem,
            completed: false
        }
       }

     },

     //function to complete item from object array
     completedItem: (state, action) => {
        state.data =
        {
         ...state.data,
         [action.payload.id]: {
             content: action.payload.content,
             completed: true
         }
        }

     }
}     

});

export const {addItem, editItem, deleteItem, completedItem} =
 toDoSlice.actions;

export default toDoSlice.reducer;
s3fp2yjn

s3fp2yjn1#

你的例子的问题在于你把data设置成了一个对象,除非你有一个很好的理由,否则你不应该这么做,而事实似乎并非如此。
取代:

createSlice({
  //...
  initialState: {
    nextId: 2,
    data: { // 👈 object
      1: {
        content: 'Content 1',
        completed: false
      }
    }
  }
  // ...
})

您应该使用:

createSlice({
  // ...
  initialState: {
    nextId: 2,
    data: [{ // 👈 array
      content: 'Content 1',
      completed: false
    }]
  }
  // ...
})

现在data具有所有可用的数组方法,包括.filter()1
无论出于什么原因,如果要将data保留为对象,可以使用

delete data[key]

其中key是要删除的对象属性。(例如:如果要删除1,请使用delete.data.1delete data['1'])。
但我强烈建议将data更改为数组。

    • 备注**:
      1-请注意,您需要修改所有约简器以处理数组。例如:
{
  reducers: {
    addItem: (state, action) => {
      state.data.push({
        content: action.payload.content,
        completed: false
      })
    }
  }
}

很有可能你不再需要state.nextId了,这就是处理数组的好处,你不需要知道当你添加一个项时你分配给了key/index

相关问题