Immer - 改变新创建的嵌套对象

Immer - Mutate Newly Created Nested Object

我正在使用 immer(通过 redux-toolkit 中的 createSlice)来管理 redux 应用程序中的状态。我编写了一个 reducer,它接收音乐曲目的有效载荷并将它们添加到用户库中。在某种程度上,此减速器还必须为每个曲目创建艺术家条目。

createTracks(draft, action: PayloadAction<{ tracks: Array<ITrack> | ITrack; }>) {
  ...
  tracks.forEach((track, index) => {
    ...
      // Check to see if artist exists, if not create, if so, add this track
      let artist = draft.artists[artistId];
      if (!artist) {
        console.log("creating artist", track.artist);
        draft.artists[artistId] = produce({
          name: track.artist,
          albums: [],
          id: artistId,
          tracks: [track.id]
        }, (artistDraft): IArtist => {
          console.log("producing the artist");
          return artistDraft;
        });
      } else {
        console.log("updating artist");
        draft.artists[artistId].tracks.push(track.id);
      }

这适用于每位艺术家的第一首曲目。但是,当 immer 创建每个新的艺术家对象并将其添加到状态时,它会使每个对象的轨道数组不可扩展。

Uncaught TypeError: Cannot add property 1, object is not extensible
      

抛出
draft.artists[artistId].tracks.push(track.id);

我推测这是因为我没有正确创建嵌套的艺术家草稿,或者 redux 不支持这种行为。这就是为什么我从使用纯对象转向使用嵌套的 immer draft - 但这似乎不起作用。

我也试过了...

draft.artists[artistId].tracks = [...draft.artists[artistId].tracks, track.id];

...但在这种情况下,tracks 属性 是只读的。

如何在没有错误的情况下执行此操作?

我终于查到了这个。我的 reducer 编写正确,但在堆栈的更高层,我不小心从 redux-immer 而不是 redux 本身导入了 combineReducersredux-immer 是一个用于将 immer 集成到 redux 中的库。

这导致 运行 我的商店两次通过 immer(一次通过 createSlice,一次通过 combineReducers),这导致......意外的......行为,包括 immer 锁定本身,导致上述对象被锁定。

毫无疑问,这是度过过去两周的一种有趣方式。