Javascript 为什么Redux示例将空对象作为第一个object.assign()参数传递?
在的todoMVC示例中,用于处理TODO的减速器具有以下行:Javascript 为什么Redux示例将空对象作为第一个object.assign()参数传递?,javascript,reactjs,redux,Javascript,Reactjs,Redux,在的todoMVC示例中,用于处理TODO的减速器具有以下行: export default function todos(state = initialState, action){ ... case EDIT_TODO: return state.map(todo => todo.id === action.id ? Object.assign({}, todo, { text: action.text }) :
export default function todos(state = initialState, action){
...
case EDIT_TODO:
return state.map(todo =>
todo.id === action.id ?
Object.assign({}, todo, { text: action.text }) :
todo
)
}
这部分代码处理更新特定todo项目。我这里的问题是,因为state.map()总是返回一个新数组。那么,是否仍有必要:
Object.assign({}, todo, { text: action.text})
难道它只是:
Object.assign(todo, { text: action.text})
更新 我理解
Object.assign({},blah…)和Object.assign(obj,blah…)之间的区别。让我重新表述我的问题:
Redux希望还原程序返回一个新状态,而不是改变现有状态。我明白了。在我的示例中,我有一个对象数组。我想交换前两个元素的顺序。看看这本书
由于Array.map始终返回一个新数组,因此对返回数组的引用需要是一个新数组。检查
但是,返回数组中的元素并非都是新的。对前两个元素的引用是新的。然而,第三项并非如此。它与旧数组中的第三项相同
所以我的问题是关于第三个元素,我应该使用:
Object.assign({},第三个元素)
或简单地返回第三个元素
Redux是想要一个新数组,其中每个对象都有新的引用(即使这些新对象中存储的值与旧对象相同),还是只想要一个新数组,其中只有更新的元素是新的?这就是object.assign
的工作原理。它返回目标对象作为其操作的返回值。因此,在第一种语法中:
Object.assign({}, todo, { text: action.text})
您正在创建一个全新的对象,其可枚举属性为todo
和{text:action.text}
如果您这样做:
Object.assign(todo, { text: action.text})
然后,todo
本身就是目标对象,因此它将被改变,这将是从对象返回的内容。assign
第一种方法是通过创建全新对象的新数组,使映射操作完全不可变
这里有一个jsbin,它说明了我的意思。请注意,在第一个示例中,数组中的原始对象已更改,这意味着状态已发生变化。在第二种情况下,原始对象保持不变:
我想补充sma的好答案,并解释为什么需要从对象返回新对象。分配
按照redux的工作方式,如果reducer返回它在状态
参数中收到的相同引用,redux将假定状态没有更改,并且不会更新视图。为了告诉redux您正在更改状态,必须返回一个新引用。这就是为什么您总是会看到一个新的空对象{}
作为对象的第一个参数。在reducer中分配。Dan Abramov(Redux的创建者)的推特:
常见的Redux误解:您需要深入克隆状态。现实:如果里面的东西没有改变,保持它的引用不变
根据redux的文档,我们不应该改变状态。在第一种情况下,数组是新的,正在更新的特定项也是新的,但是,其余项不是新的,对吗?看看这个:用一个jsbin编辑了我的答案,希望能让它更清楚。