如果我完全替换了整个状态片段,我是否还必须使用Object.assign或spread运算符来复制原始状态并将其替换为新状态,或者我是否可以返回新状态在我的减速机?
const fetching = (state = { isFetching: false },action) => {
switch (action.type) {
case 'REQUESTING':
return Object.assign({},state,{ isFetching: true } )
case 'RECEIVE_POKEMON_TYPE_INFO':
return Object.assign({},{ isFetching: false } )
default:
return state
}
}
与
const fetching = (state = { isFetching: false },action) => {
switch (action.type) {
case 'REQUESTING':
return { isFetching: true }
case 'RECEIVE_POKEMON_TYPE_INFO':
return { isFetching: false }
default:
return state
}
}
最佳答案
这里有几件事情.基本上,如果您的状态只包含一个布尔变量,那么通过枚举创建一个新对象就可以了.但是,如果您的状态包含其他内容,则执行object.assign应该可以正常工作.
然而(并且并不总是’然而’),如果你的状态很复杂 – 那就是它由其他对象组成然后做object.assign将无法正确复制字段 – 它复制了引用而不是值.例如,如果您的状态由“currentSelectedPokemon”字段组成,那么值是一个Pokemon对象,然后Object.assign将复制对该pokemon对象的引用.它不会复制对象本身.为了更容易地显示它,请查看下面的代码 – 它为obj2打印“value2”.
var obj1 = {
field: {
subfield: "value"
}
};
var obj2 = Object.assign({},obj1);
obj1.field.subfield = "value2";
console.log(JSON.stringify(obj2,null,2));
有两种方法可以解决这个问题.第一种是对所有州使用Immutable库.但是,我发现将复杂对象转换为Immutable和back的开销提供了足够的复杂性,从而引入了不必要的错误.所以现在我这样做:
const fetching = (state = { isFetching: false },action) => {
switch (action.type) {
case 'REQUESTING':
const newState = JSON.parse(JSON.stringify(state));
newState.isFetching = true;
return newState;
case 'RECEIVE_POKEMON_TYPE_INFO':
const newState = JSON.parse(JSON.stringify(state));
newState.isFetching = false;
return newState;
default:
return state
}
}
事实证明,JSON.parse(JSON.stringify(object))是一种快速可靠的方法来制作一个vanilla java对象的副本.它剥离了所有功能(这是我通常想要的).它很快,因为浏览器通常在本机代码中实现这些功能.