【问题标题】:Delete element from array in nested object?从嵌套对象的数组中删除元素?
【发布时间】:2016-11-23 19:22:46
【问题描述】:

我该怎么做?我的店铺是这样的:

{
   ...,
   playlist : [
      ...,
      {
          id : 1,
          title :  "fancy-playlist-title",
          songs : [
             { id : 1 },
             { id : 2 },
             ... and so on
          ]
      }
   ]
}

我有这个减速器:

if(action.type === "REMOVE_FROM_PLAYLIST"){
        return {
            ...state,
            playlist : [
                ...state.playlist,
                ...state.playlist[action.index].songs.splice(0, action.indexSongs),
                ...state.playlist[action.index].songs.splice(action.indexSongs+1)
            ]
        }
    }

更新

每个播放列表可以有无限的歌曲,因为播放列表数组包含很多这样的播放列表对象

playlist : [
   {
      id : 1,
      title : "title",
      songs : []
   },{
     id : 2,
     title : "playlist 2",
     songs : []
   },
   {... and so on}
]

我的完整reducer是这样的

export default function(state = {}, action) {

if(action.type === "REMOVE_FROM_PLAYLIST"){

        //action.index : current index of playlist
        //action.indexSongs : current index of song that I want to delete from current playlist

        let playlist = state.playlist[action.index].slice(0, action.index).concat(state.playlist[action.index].slice(action.index + 1));
        return {
            ...state,
            playlist : [
                ...state.playlist,
                ...playlist.slice(0, action.indexSongs),
                ...playlist.slice(action.indexSongs + 1)
            ]
        }
    }

return state;
}

我的问题是如何删除一个播放列表中的一首歌曲?我正在发送当前播放列表的索引和当前播放列表的歌曲索引。

【问题讨论】:

  • 只是为了将来 - 考虑使用 immutable.js - 你可以更轻松地操作它们。

标签: javascript reactjs ecmascript-6 redux


【解决方案1】:

splice 改变数组状态,你不应该这样做。

你想要的是 sliceconcat 的组合:

playlist.slice(0, indexOfSong)  // copy a portion of the array
                                // from the start to the indexOfSong

        .concat(                // concatenate it with:

          playlist.slice(indexOfSong + 1)
                                // copy of a portion of the array from
                                // the index just after indexOfSong
                                // to the end of the playlist
        );

上面可以用 ES6 Spread 语法写成如下:

[
  ...playlist.slice(0, indexOfSong)
  ...playlist.slice(indexOfSong + 1));
]

编辑,考虑到您最近的问题更新,您的减速器应该看起来像 这个:

export default function(state = {}, action) {

if(action.type === "REMOVE_FROM_PLAYLIST"){
  return {
            ...state,
            playlist : [
                ...state.playlist,
                ...playlist[action.index].songs.slice(0, action.indexSongs),
                ...playlist[action.index].songs.slice(action.indexSongs + 1)
            ]
        }
    }
}

【讨论】:

  • 本例中为"concat(list.slice(indexOfSong + 1);",list是什么意思?this.state.playlist[action.index]?,感谢帮助太快了
  • 错字:) 现已更正
  • 我想我会对此进行一些扩展,所以添加了一些 cmets,希望对您有所帮助
  • 非常感谢您的帮助,但是按照您的代码示例,我收到一条错误消息,提示“未定义不是函数 state.playlist[action.index].slice(0,action. indexOfSong)"
  • 您确定state[action.index] 解析为数组吗?你能贴出你完整的减速器吗?另请查看我使用 ES6 扩展语法的替代语法。
【解决方案2】:

如果你使用 lodash,你可以使用 _.merge

https://lodash.com/docs/4.17.2#merge

if(action.type === "REMOVE_FROM_PLAYLIST"){
    let newPlaylistWihoutDeletedItem = state.playlist.splice(action.index, 1);

    return _.merge({}, state, {
      playlist: newPlaylistWihoutDeletedItem
    });
}

【讨论】:

  • redux 中不允许突变reducers
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2022-07-19
  • 2021-12-11
  • 2019-01-25
  • 1970-01-01
  • 2019-12-17
相关资源
最近更新 更多