1、使用lodash的_.cloneDeep()函数
深复制,可以递归复制复杂的对象,Object.assign()和_.assign()只会复制对象的第一层属性,更深层次的属性是引用赋值的,指向同一对象
const newState = cloneDeep(state)
newState.name = action.name
return newState
2、使用官方提供的update
import update from 'react-addons-update';
update(state, {
name: action.name,
})
下面看下update是如何工作的
function update(object, spec) {
if (!(Array.isArray(object) && Array.isArray(spec))) {
invariant(
!Array.isArray(spec),
'update(): You provided an invalid spec to update(). The spec may ' +
'not contain an array except as the value of $set, $push, $unshift, ' +
'$splice or any custom command allowing an array value.'
);
}
invariant(
typeof spec === 'object' && spec !== null,
'update(): You provided an invalid spec to update(). The spec and ' +
'every included key path must be plain objects containing one of the ' +
'following commands: %s.',
Object.keys(commands).join(', ')
);
var nextObject = object;
var specKeys = getAllKeys(spec);
var index, key;
// 遍历 属性变化对象的属性
for (index = 0; index < specKeys.length; index++) {
key = specKeys[index];
if (hasOwnProperty.call(commands, key)) {
nextObject = commands[key](spec[key], nextObject, spec, object);
} else {
// 递归更新更深层次的对象
var nextValueForKey = update(object[key], spec[key]);
if (nextValueForKey !== nextObject[key]) {
if (nextObject === object) {
nextObject = copy(object);
}
nextObject[key] = nextValueForKey;
}
}
}
return nextObject;
}
}
第二种方法相对于前者来说不需要深复制state对象,redux是根据newState === state判断state是否改变的,所以reducer必须生成一个新的对象