...状态到底能做什么?

时间:2018-10-01 19:54:46

标签: javascript angular ngrx-store

我正在下面的示例中试用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{}和三个附加属性。

4 个答案:

答案 0 :(得分:2)

状态的要点是它是不变的(返回一个新对象,而不是修改后的对象)。因此,如果要修改状态并为其添加新值,则需要返回当前状态以及要添加到先前状态的新值。在使用传播运算符...的示例中,您将返回一个新的不可变对象,该对象包含以前的状态以及三个新属性requestinghasErrorstatus。您可以考虑这样做:

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中的参考更改,而不是比较对象按属性比较属性。这是性能上的一大优势。

Use of Spread Operator with Redux

答案 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付费课程中推荐了这个库。