我下面有这个对象,我想测试当我执行操作来更改
group
键的状态时,它会正确更新。正如您所看到的,该对象中有更多的键值对,而不仅仅是 group
,因此我想扩展 initialState
对象并编写我的测试,仅更改 group
值。
这是初始状态:
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
展开一次,然后在过滤器对象中再次展开 initialState.filters
只是为了操纵月份。
在我看来这应该很好用:
const state = reducer(
{
...initialState,
filters: {
group: "daily"
}
},
action
);
我的问题是为什么我需要添加
initialState.filters
行才能使此测试可行。请有人帮我理解吗?我已经研究过但找不到任何东西。
当您执行
...initialState.filters
时,您正在将 filters
对象散布在 initialState
上。您必须执行此操作,因为您刚刚在减速器中定义了一个新的 filters
对象,因此必须在其中放置您想要从旧版本中保留的值。
如果这一切看起来有点冗长,那么请查看 Immer,它允许您使用更传统的 API 来拥有不可变对象
JavaScript 的扩展运算符相当愚蠢;它不会像某些库提供的那样尝试进行任何类型的智能合并。当您添加
filters
属性时,JavaScript 只会覆盖 initialState
的扩展 filters
定义。
您可以将代码示例视为大致相当于
Object.assign(
{},
initialState,
{
filters: { ... }
})