Javascript 从react对象复制状态时,为什么必须将对象展开两次
我在下面有一个对象,我想测试一下,当我执行一个操作,将Javascript 从react对象复制状态时,为什么必须将对象展开两次,javascript,reactjs,unit-testing,javascript-objects,spread,Javascript,Reactjs,Unit Testing,Javascript Objects,Spread,我在下面有一个对象,我想测试一下,当我执行一个操作,将组的状态更改为正确更新的状态时。正如您所看到的,这个对象中的键值对远远多于组,因此我想扩展初始状态对象,并编写我的测试,只更改组值 以下是初始状态: export const initialState = { testing: false, filters: { start: moment() .startOf("month") .format(), end: moment() .e
组的状态更改为正确更新的状态时。正如您所看到的,这个对象中的键值对远远多于组
,因此我想扩展初始状态
对象,并编写我的测试,只更改组
值
以下是初始状态:
export const initialState = {
testing: false,
filters: {
start: moment()
.startOf("month")
.format(),
end: moment()
.endOf("month")
.format(),
city: "",
group: "daily"
},
locations: []
};
我的单元测试:
test("It performs the setGroup action correctly", () => {
const active = "month";
const action = setGroup(active);
const state = reducer(
{
...initialState,
filters: {
...initialState.filters,
group: "daily"
}
},
action
);
expect(state).toEqual({
...initialState,
filters: {
...initialState.filters,
group: "month"
}
});
});
此测试有效,但是我想知道为什么我必须传播initialstate
一次,然后在filters对象中再次传播initialstate。filters
再次传播只是为了操纵月份
在我看来,这应该很好:
const state = reducer(
{
...initialState,
filters: {
group: "daily"
}
},
action
);
我的问题是为什么我需要将行initialState.filters
放入测试中。有人能帮我理解吗?我做过研究,但什么也找不到。JavaScript的扩展操作符相当愚蠢;它不会像一些图书馆提供的那样尝试进行任何形式的智能合并。当您添加过滤器
属性时,JavaScript只会覆盖初始状态
的扩展过滤器
定义
您可以认为您的代码示例大致相当于
Object.assign(
{},
initialState,
{
filters: { ... }
})
JavaScript的扩展操作符相当愚蠢;它不会像一些图书馆提供的那样尝试进行任何形式的智能合并。当您添加过滤器
属性时,JavaScript只会覆盖初始状态
的扩展过滤器
定义
您可以认为您的代码示例大致相当于
Object.assign(
{},
initialState,
{
filters: { ... }
})
当您执行…initialState.filters
时,您正在扩展initialState
上的filters
对象。您必须这样做,因为您刚刚在reducer中定义了一个新的过滤器
对象,因此必须在其中放置希望保留旧版本的值
如果这一切看起来有点冗长,那么请查看Immer,它允许您使用更传统的API创建不可变对象
当您执行…initialState.filters
时,您正在initialState
上展开filters
对象。您必须这样做,因为您刚刚在reducer中定义了一个新的过滤器
对象,因此必须在其中放置希望保留旧版本的值
如果这一切看起来有点冗长,那么请查看Immer,它允许您使用更传统的API创建不可变对象
这有助于我理解。因此,为了澄清,当我第一次传播initialState
对象时,我将对象作为一个整体进行新的复制。然后,我必须从这个新的initialState
中说一些类似的话,我想保留filters对象(…initialState.filters
)和组
值在其中。几乎,当您向其添加或更改值时,您已经在重新定义过滤器时执行了第二个操作。这有助于我理解。因此,为了澄清,当我第一次传播initialState
对象时,我将对象作为一个整体进行新的复制。然后我必须从这个新的initialState
中说一些类似的话,我想保留filters对象(…initialState.filters
)和组
值在其中。几乎,当您向其添加或更改值时,在重新定义filters
时,您已经执行了第二个操作。