简体   繁体   中英

Deleting object from state removes key of parent object

I have this object in state

 tasks: [
            {
                'Day 1': [
                    {
                        id: 1234,
                        task: 'Task 1',
                        created: 'somedate'
                    },
                    {
                        id: 1235,
                        task: 'Task 2',
                        created: 'somedate'
                    },
                    {
                      id: 1225,
                      task: 'Task 3',
                      created: 'somedate'
                  }
                ],   
            },
            {
              'Day 2': [
                    {
                        id: 12234,
                        task: 'Task 4',
                        created: 'somedate'
                    },
                    {
                        id: 12235,
                        task: 'Task 5',
                        created: 'somedate'
                    },
                ],    
            },        
    ],

and function that deletes object of array by given id

_deleteTask = (id) => {
      const tasks = [...this.state.tasks];
      const updatedTasks = tasks.map((item) =>   
      { return Object.values(item).map((boxForTask) => {
          return Object.values(boxForTask).map((eachTaskBox =>  { 
            if (eachTaskBox.id !== id) return eachTaskBox

            }));
      })}
      );
      this.setState({ tasks: updatedTasks });
    }

it deletes the task containing the id, but also deletes the outer key that marks day. I can't seem to find the answer why actions nested deeply affect the outer key

Your code as it is, isn't doing what you are expecting it to do, or it does to much (eg, the unneccessary copy of the state.tasks into updatedTasks ). This copy is not necessary, because map will already produce a new array for you, so in a sense you are copying it twice.

You are removing the outer property when you are returning

return Object.values(item).map((boxForTask) => { /*...*/ } );

as this will go only into the values of each of these properties, you don't have a clue what your properties might be afterwards.

Another interesting piece of code would be the inner map , where you should probably use filter (otherwise, you would have some undefined in the resulting output). A filter would just return the matching items, whereas map would return all items

To update your current code, you could simply do it in the following way

function copyOfTasksWithoutId(tasks, id) {
  return tasks.map(task => {
    return Object.keys(task).map(key => {
      return {
        [key]: task[key]
          .filter(taskWithId => taskWithId.id !== id)
      };
    });
  });
}

The result will be a copy of the tasks array, with a matching outer property and the tasks that should be removed will be deleted. It will not mutate the original input, so that would fit your needs in react as well (for this reason, I also print the original array after the filtered one in the below snippet)

 const tasks = [{ 'Day 1': [{ id: 1234, task: 'Task 1', created: 'somedate' }, { id: 1235, task: 'Task 2', created: 'somedate' }, { id: 1225, task: 'Task 3', created: 'somedate' } ], }, { 'Day 2': [{ id: 12234, task: 'Task 4', created: 'somedate' }, { id: 12235, task: 'Task 5', created: 'somedate' }, ], }, ]; function copyOfTasksWithoutId(tasks, id) { return tasks.map(task => Object.keys(task).map(key => ({ [key]: task[key] .filter(taskWithId => taskWithId.id !== id) }) ) ); } console.log(copyOfTasksWithoutId(tasks, 12234)); console.log(tasks);

Perhaps something like the following would work for you? This approach achieves the delete/filtering behaviour based on Array#reduce() , Array#map() and Object#entries() :

 var state = { tasks : [ { 'Day 1': [ { id: 1234, task: 'Task 1', created: 'somedate' }, { id: 1235, task: 'Task 2', created: 'somedate' }, { id: 1225, task: 'Task 3', created: 'somedate' } ], }, { 'Day 2': [ { id: 12234, task: 'Task 4', created: 'somedate' }, { id: 12235, task: 'Task 5', created: 'somedate' }, ], } ] }; const _deleteTask = (id) => { const tasks = state.tasks.map(task => { return Object.entries(task).reduce((t, entry) => { const dayKey = entry[0]; const dayArray = entry[1].filter(dayItem => dayItem.id !== id); t[ dayKey ] = dayArray; return t; }, {}); }); state.tasks = tasks; // this.setState({ tasks: updatedTasks }); }; console.log('Before', state); _deleteTask(12235); console.log('After', state);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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