我正在下面的示例中试用Angular中的NgRx(redux)和...state
,我无法完全理解。我进行了搜索,并通常将其理解为散布,但不确定为什么Interface State
中的数据属性会在化简器return{}
的{{1}}块中重复,就像... 传播吗?有人可以帮我理解吗?
switch
PS:我看过线程here,并且得到的散布效果确实如此,散开了。但是在Redux / NgRx的上下文中,试图理解export interface State {
sessionData: Map<string, string>;
requesting: boolean;
hasError: boolean;
status: StatusModel;
}
export function sessionReducer(state: State = INITIAL_STATE, action: Session.Actions): State {
switch (action.type) {
case Session.REQUEST_SESSION_DATA:
return {
...state,
requesting: true,
hasError: false,
status: undefined,
};
}
}
为什么具有return{}
和三个附加属性。
答案 0 :(得分:2)
状态的要点是它是不变的(返回一个新对象,而不是修改后的对象)。因此,如果要修改状态并为其添加新值,则需要返回当前状态以及要添加到先前状态的新值。在使用传播运算符...
的示例中,您将返回一个新的不可变对象,该对象包含以前的状态以及三个新属性requesting
,hasError
和status
。您可以考虑这样做:
export function sessionReducer(state: State = INITIAL_STATE, action: Session.Actions): State {
switch (action.type) {
case Session.REQUEST_SESSION_DATA:
state.requesting = true;
state.hasError: false;
state.status: undefined;
return state;
}
}
但是您不能这样做,因为您破坏了国家的哲学,即新的不可变对象,而不是修改过的对象:)
在您的示例中,我们需要了解INITIAL_STATE
的初始化方式,但是我认为它仅包含sessionData
属性。因此,在该示例中,您将返回sessionData
以及其余属性。
在下面的链接中,您可以看到spread运算符是Redux世界中常用的运算符,用于将当前状态作为新对象返回(这是Redux for React示例,但在Angular中的工作原理完全相同)。
在Angular中,使用Redux
模式和OnPush
更改检测策略是一种非常常见的模式,因为您要告诉Angular仅检查组件@Input
中的参考更改,而不是比较对象按属性比较属性。这是性能上的一大优势。
答案 1 :(得分:1)
$versionText=(Get-Item MyProgram.exe).VersionInfo.FileVersion
(Get-Content MySetup.vdproj.template).replace('${VERSION}', $($versionText)) | Set-Content MySetup.vdproj
被称为spread operator。
Spread运算符从该对象“解包”所有东西。
...
与
相同return {
...state,
requesting: true,
hasError: false,
status: undefined,
};
答案 2 :(得分:0)
您正确的是,这是spread operator。基本上,它提取给定对象上的所有属性。另一种写法是:
let newState = {
sessionData: state.sessionData,
requesting: state.requesting,
hasError: state.hasError,
status: state.status
};
newState.requesting = true;
newState.hasError = true;
newState.status = undefined;
return newState;
价差运算符使您省去了知道所有属性被调用的工作,并确保所有未更改的值都照原样保留。
换种方式
{ ...state }
制作state
的浅表副本。然后,您可以随意更改该浅表副本。
答案 3 :(得分:0)
这就是说,返回一个具有状态所有属性的新对象,并添加/修改其他3个属性。
值得知道的是{...state}
等于state
使得:
_.isEqual(state, {...state}) // returns true
但是:
{...state} !== state
这是因为{}
创建了一个新对象,而散布运算符只是向该对象添加了道具。因此,状态的对象引用与新对象引用不同。这就是更改检测通常如何工作的方式。它看起来是否对象引用已更改。如果有,它将知道有更改并采取相应的措施。之所以使用这种方法,是因为它比检查深度相等性要快得多,后者必须检查所有属性。
归约器通常在只想修改状态的属性之一的地方使用散布运算符。如果他们这样做:
state.requesting = true
return state
然后,在此示例中,对象引用未更改,因此更改检测不会生效,您已被填充。
要强制执行变更检测,有一个名为ngrx-store-freeze的小巧的lib,它可以防止您意外更改状态,从而导致许多难以重现的错误。实际上,Udemy在他们的ngrx付费课程中推荐了这个库。