【发布时间】:2021-12-31 11:10:39
【问题描述】:
我正在使用 immer(通过 redux-toolkit 中的 createSlice)来管理 redux 应用程序中的状态。我编写了一个reducer,它接收音乐曲目的有效负载并将它们添加到用户库中。在某种程度上,这个 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 不支持这种行为。这就是为什么我从使用纯对象转向使用嵌套的浸入式草稿的原因——但这似乎不起作用。
我也试过了……
draft.artists[artistId].tracks = [...draft.artists[artistId].tracks, track.id];
...但在这种情况下,tracks 属性是只读的。
我怎样才能在没有错误的情况下实现这个?
【问题讨论】:
-
请问您为什么要在已经浸入式减速器中使用生产?只是创建新对象应该具有相同的效果,除非您想修改来自操作的外部数据源的某些属性。
-
调试下面的内容很糟糕。绝对不是正确的做法。
标签: javascript typescript redux redux-toolkit immer.js