你正在改变数组 . 使用redux,您必须始终返回您修改的任何内容的新副本 .
return {...state, lists: [...state.lists, action.item]};
切片工作而不是推送的原因是因为.slice返回数组的新副本 . 推变异 .
此外,Object.assign的工作方式......它创建了一个新的根对象,但它不能递归地工作 . 需要研究的东西: Value 和参考类型之间的差异 . 值类型包括字符串,数字,布尔值,null或未定义 . 这些东西都是原始值,可以直接比较 . 但是,引用类型类似于对象或数组或自定义类或函数的任何实例 . 从本质上讲,即使它们具有相同的内容,也无法直接进行比较 .
例如:
var foo = ['foo']
var bar = ['foo']
// foo === bar : false
var a = Object.assign({}, {foo: foo})
// a.foo === foo : true
var b = Object.assign({}, {foo: foo}, {foo: bar})
// b.foo === bar : true
// b.foo === foo : false
基本规则是在主reducer内部有嵌套对象(如数组或对象)的任何时候 - 如果对其进行更改,则必须返回新副本 .
redux正在发生的事情正如你在 var a 中看到的那样 . 即使您更新了数组的内容,redux也只是对reducer的每个根键进行严格的相等检查,以确定它是否应该更新组件 . 因此,当您返回推送的数组时,它会将该对象视为与先前状态相同 - 因为在两种情况下它都是相同的数组实例 . Redux不考虑数组(或对象)中的内容 .