我有一个名为
stories
的商店,其中存储了 userStories
对象。
商店内
userStories
物体示例:
userStories: {
userId1: [{storyId: 1, viewedBy: [id5, id2, id9]}, {storyId: 2, viewedBy: [id1, id2, id3]}]
userId2: [{storyId: 6, viewedBy: [id25, id42, id29]}, {storyId: 7, viewedBy: [id21, id22, id33]}]
}
我在我的主页组件中订阅特定
userId
的故事,如下所示:
const stories = useSelector((state) => state.stories.userStories[userId])
当用户单击组件中的按钮时,我会调度一个名为
updateStories
的方法,该方法采用故事 id 的 array
以及用户 id。它应该更新特定用户 ID 的所有故事对象。
这是减速机:
updateStoryViewedBy: (state, action) => {
const { storyIds, storyCreatorId} = action.payload
const stories = state.userStories[storyCreatorId]
// loop over all story ids => find them in users stories => update them each individually
storyIds.forEach((id) => {
const s = stories?.find((s) => s?._id === id)
s.isSeen = true
})
},
这里我直接改变状态。如果
storyIds
包含 n
id,则商店将直接突变 n 次,每个与故事 id 匹配的对象变化一次。由于对商店的每个直接突变都会导致重新渲染订阅该商店的组件,因此理论上,这会在使用 Home
订阅商店时更新 n
组件 useSelector
次。但是我的 Home
组件没有重新渲染 n
次。
这是为什么,在reducer方法中使用循环来更新数组中的各个对象在
redux-tookit
中被认为是有问题的?
也许使用
state.userStories[userId] = state.userStories[userId].map(...)
只更新一次存储并避免变异会更有利吗?谢谢
这里我直接改变状态。如果storyIds包含n个id, 然后 store 直接变异 n 次,每个对象一次 匹配故事 ID。由于商店的每个直接突变都会导致 重新渲染到订阅该商店的组件,这将在 理论上,当使用 useSelector 时,会更新 Home 组件 n 次 订阅商店。但是我的 Home 组件没有重新渲染 次。
我相信每个突变导致重新渲染的假设在这里不会发生。浅层相等检查可能不会看到每个更改,因为您正在“直接改变状态”,而您通常不应该这样做。我认为这应该是编写减速器来创建新数组而不是更新当前数组的更好方法。不太确定这里的逻辑,所以如果您遇到任何问题,请告诉我
updateStoryViewedBy: (state, action) => {
const { storyIds, storyCreatorId } = action.payload;
const stories = state.userStories[storyCreatorId];
if (stories) {
const updatedStories = stories.map(story => {
if (storyIds.includes(story._id)) {
return { ...story, isSeen: true };
}
return story;
});
state.userStories[storyCreatorId] = updatedStories;
}
}