Javascript 国家到底做什么?

Javascript 国家到底做什么?,javascript,angular,ngrx-store,Javascript,Angular,Ngrx Store,我正在尝试NgRx(redux)的角度和…状态,在下面的例子中,我不能完全理解。我搜索了它,通常将其理解为spread,但不确定为什么接口状态中的数据属性会在reducer的开关的返回{}块中重复,因为。。。你会传播它们吗?有人能帮我理解吗 export interface State { sessionData: Map<string, string>; requesting: boolean; hasError: boolean; status: StatusMo

我正在尝试NgRx(redux)的角度和
…状态,在下面的例子中,我不能完全理解。我搜索了它,通常将其理解为spread,但不确定为什么
接口状态
中的数据属性会在reducer的
开关
返回{}
块中重复,因为。。。你会传播它们吗?有人能帮我理解吗

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,
          };
      }
}
导出接口状态{
会期数据:地图;
请求:布尔;
hasrerror:布尔型;
状态:状态模型;
}
导出函数sessionReducer(状态:state=初始状态,操作:Session.Actions):状态{
开关(动作类型){
案例会话。请求会话数据:
返回{
……国家,
请求:是的,
错误:错,
状态:未定义,
};
}
}

附言:我已经看过了线,通常得到的是排列,就是这样,排列。但是在这里,在Redux/NgRx的上下文中,试图理解为什么
返回{}
具有
..状态
和三个附加属性。

..
被调用

Spread操作符“解包”该对象的所有内容

return {
    ...state,
    requesting: true,
    hasError: false,
    status: undefined,
};

return {
    sessionData: state.sessionData,
    requesting: state.requesting,
    hasError: state.hasError
    status: state.status,
    requesting: true,
    hasError: false,
    status: undefined,
};

你是对的,这是正确的。基本上,它提取给定对象上的所有属性。另一种写法是:

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;
spread操作符可以省去您了解所有属性的调用,并确保所有未更改的值都按原样进行传递

换言之

{ ...state }

制作
状态的浅层副本
。然后,您可以随意修改该浅层副本。

状态的要点是它是不可变的(返回一个新对象,而不是一个修改过的对象)。因此,如果要修改状态并向其添加新值,则需要返回当前状态加上要添加到以前状态的新值。在该示例中,使用扩展运算符
,您将返回一个新的可变对象,该对象包含以前的状态加上三个新属性
请求
hasrerror
状态
。您可以考虑这样做:

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\u状态是如何初始化的,但我认为它只包含
sessionData
属性。因此,在该示例中,您将返回
sessionData
以及其余属性

在下面的链接中,您可以看到spread操作符是Redux世界中常用的操作符,用于将当前状态作为新对象返回(例如,它是Redux,但在Angular中的作用完全相同)

在Angular中,使用
Redux
模式和
OnPush
更改检测策略是非常常见的模式,因为您告诉Angular只检查组件
@Input
中的引用更改,而不是逐个属性比较对象。这是性能上的一大优势


这是说返回一个包含state所有属性的新对象,并添加/修改3个附加属性

值得知道的是,
{…state}
深深地等于
state
,因此:

_.isEqual(state, {...state}) // returns true
但是:

这是因为
{}
创建了一个新对象,而spread操作符只是向该对象添加道具。因此,状态的对象引用与新对象引用不同。这就是变更检测通常的工作方式。它查看对象引用是否已更改。如果有,它知道有变化,并相应地采取行动。之所以使用这种方法,是因为它比检查深度相等要快得多,因此必须检查所有属性

还原程序通常使用扩展运算符,它们只想修改状态的一个属性。如果他们这样做了:

state.requesting = true
return state
然后在本例中,对象引用没有更改,因此更改检测不起作用,您将被填充


为了加强变更检测,有一个很棒的小库,名为lib,它可以防止您意外地改变状态,从而导致许多难以重现的bug。这个lib实际上是Udemy在他们的付费ngrx课程上推荐的。

听起来它应该只包括
sessionData
,而不是
…state
,假设
state
只包含这些属性而不包含其他sok,所以@CertainPerformance注释掉后,返回值应该是“{…state}”然后呢?我想,当你实际上只想要一个对象的一个属性时,散布一个对象似乎是毫无意义的?(我不太明白为什么原始代码使用spread)@CertainPerformance正是我的困惑所在。因此,我认为我误解了…|@Vivek,或者对它有一个理解上的差距。它保护你不受状态更新的影响。如果以后决定向状态添加更多属性,则不必记住在复制特定属性的任何地方都进行更新。这也会减少输入。谢谢,我会在这个链接上读更多。
state.requesting = true
return state