我在学习Redux。但是,我知道还原器是一个接收当前状态和动作对象的函数,然后决定如何更新状态、复制状态、更新深度复制的状态并最终返回新状态。
因此,下面的代码就是一个典型的例子:
const initialState = { value: 0 }
function counterReducer(state = initialState, action) { // Check to see if the reducer cares about this action if (action.type === 'counter/increment') {
// If so, make a copy of `state`
return {
...state,
// and update the copy with the new value
value: state.value + 1
} } // otherwise return the existing state unchanged return state }
但是,您会意识到,它正在使用spread操作符来复制状态。spread操作符只对它做了一个浅拷贝。因此,这意味着状态不应该是多维对象?
因为,据我所知,扩展运算符不适用于多维数组或对象。如果它是多维的,则通过引用而不是按值复制值。这就是如果您真的想要对对象或数组进行深度复制的原因,您可以使用Lodash库、structuredClone甚至JSON.parse(JSON.stringify(此处为“您的对象/数组”)。
那么,有人知道如果这个存储只是Redux中的一个级别的对象存储吗?那么在本例中,使用操作符没有任何问题。或它是一种扩展运算符表示,实习生Redux对它进行了深入的克隆?。
--谢谢你!!
干杯,海龟们
发布于 2022-09-21 03:12:04
事实上,答案是,如果你有一个状态多维,你必须写你的减速器这样的工作:
function handwrittenReducer(state, action) {
return {
...state,
first: {
...state.first,
second: {
...state.first.second,
[action.someId]: {
...state.first.second[action.someId],
fourth: action.someValue
}
}
}
}
}
然而,现在我们使用的是Redux的createSlice函数,因此createSlice使用了一个名为Immer的库。
"Immer“使用一种名为Proxy的特殊JS工具来包装您提供的数据,并允许您编写”变异“包装数据的代码。但是,Immer跟踪您试图进行的所有更改,然后使用该更改列表返回一个安全更新的值,就像您手动编写了所有不可变的更新逻辑一样。”
因此,上述代码可以简化为:
function reducerWithImmer(state, action) {
state.first.second[action.someId].fourth = action.someValue
}
记住:
“您只能在Redux的createReducer
createSlice和createSlice中编写”“逻辑,因为它们在内部使用Immer!如果您在没有Immer的还原器中编写变异逻辑,它会变异状态并导致错误!”
干杯,海龟们
https://stackoverflow.com/questions/73790705
复制相似问题