为什么从我的 React 对象复制状态时我必须将我的对象展开两次
Why do I have to spread my object twice when copying state from my react object
我在下面有这个对象,我想测试一下当我执行一个操作来更改 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
行才能使该测试可行。请有人能帮我理解吗?我做了研究,但找不到任何东西。
JavaScript 的展开运算符相当愚蠢;它不会像某些图书馆提供的那样尝试进行任何类型的智能合并。当您添加 filters
属性时,JavaScript 会简单地覆盖 initialState
的传播 filters
定义。
您可以认为您的代码示例大致等同于
Object.assign(
{},
initialState,
{
filters: { ... }
})
当您执行 ...initialState.filters
时,您正在 initialState
上传播 filters
对象。您必须这样做,因为您刚刚在 reducer 中定义了一个新的 filters
对象,因此必须在其中放置您希望从旧版本中保留的值。
如果这一切看起来有点冗长,请查看 Immer,它允许您使用更传统的 API
来拥有不可变对象
我在下面有这个对象,我想测试一下当我执行一个操作来更改 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
行才能使该测试可行。请有人能帮我理解吗?我做了研究,但找不到任何东西。
JavaScript 的展开运算符相当愚蠢;它不会像某些图书馆提供的那样尝试进行任何类型的智能合并。当您添加 filters
属性时,JavaScript 会简单地覆盖 initialState
的传播 filters
定义。
您可以认为您的代码示例大致等同于
Object.assign(
{},
initialState,
{
filters: { ... }
})
当您执行 ...initialState.filters
时,您正在 initialState
上传播 filters
对象。您必须这样做,因为您刚刚在 reducer 中定义了一个新的 filters
对象,因此必须在其中放置您希望从旧版本中保留的值。
如果这一切看起来有点冗长,请查看 Immer,它允许您使用更传统的 API
来拥有不可变对象