Javascript 将Object.assign()与其他操作结合使用时,Ngrx观测值不会对状态存储更改作出反应
我很难理解为什么第一个样本似乎可以正常工作,但第二个样本很难启动观察者Javascript 将Object.assign()与其他操作结合使用时,Ngrx观测值不会对状态存储更改作出反应,javascript,angular,redux,ngrx,Javascript,Angular,Redux,Ngrx,我很难理解为什么第一个样本似乎可以正常工作,但第二个样本很难启动观察者 // Working reducer return Object.assign({}, state, { expanded: Object.assign({}, state.expanded, { clients: !state.expanded.clients }) }); // Faulty reducer - Devtools indicates a change but the observables /
// Working reducer
return Object.assign({}, state, {
expanded: Object.assign({}, state.expanded, { clients: !state.expanded.clients })
});
// Faulty reducer - Devtools indicates a change but the observables
// seem to not respond and pass on the information down the line
newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;
// Selectors
import {createSelector} from 'reselect';
export const SIDEBAR = (state: AppState) => state.sidebar;
export const SIDEBAR_UI = createSelector<AppState, SidebarUIState, SidebarState>(
SIDEBAR,
(state: SidebarState) => state.ui
);
// Sidebar service
public getSidebarUIExpandedObservable(): Observable<SidebarUIExpandedState> {
debug('Get sidebar UI expanded observable');
return this._store.select(SIDEBAR_UI_EXPANDED);
}
//工作减速器
返回Object.assign({},state{
扩展:Object.assign({},state.expanded,{clients:!state.expanded.clients})
});
//减速器故障-Devtools表示发生了变化,但可观察到
//似乎没有回应,也没有把信息传递下去
newState=Object.assign({},state);
newState.expanded.clients=!国家客户;
//选择器
从“重新选择”导入{createSelector};
导出常量边栏=(状态:AppState)=>state.SIDEBAR;
导出常量边栏_UI=createSelector(
侧边栏,
(state:SidebarState)=>state.ui
);
//边栏服务
public getSidebarUIExpandedObservable():可观察{
调试('Get sidebar UI expanded observable');
返回此。\u存储。选择(侧栏\u UI\u展开);
}
还原程序需要使用不可变对象的纯函数。
因此,您不能改变newState对象,但必须创建一个在创建时具有明确新状态的新对象
第一个示例符合不可变原则,因为Object.assign将第三个参数中对象的匹配属性复制到第二个参数中的对象副本,然后再将其分配给目标对象(第一个参数)。因此,原始状态保持不变,并且在目标对象中获得新状态。
换句话说,内存中的object.assign没有更改任何原始对象状态,返回值将提供一个随时可用(无需进一步更改)的新状态对象。
有关Object.assign()的详细信息:
在第二种情况下,首先创建了一个新对象(不变性仍然有效),随后,通过分配布尔值来改变状态,因此不变性原则被打破,并且还原程序通常不接受这一点 减速器中有以下部件:
newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;
state.expanded
的内容正在发生变化
即newState.expanded
和state.expanded
引用同一对象,并且该对象的client
属性正在发生变化。查看展开的的代码将看到对象引用未更改,并将假定内容也未更改,但您通过切换其客户端的属性的值对其进行了变异。而不是执行以下操作:
newState = Object.assign({}, state);
newState.expanded.clients = !state.expanded.clients;
做
技巧:
当您使用Typescript>=2.1.4时,您就可以这样做了
return {
...state,
{
expanded: {
...state.expanded,
{
clients: !state.expanded.clients
}
}
}
};
谢谢你们!我能接受这三个答案吗D我将等待公众的更多投票,并选择投票最多的一家使用spread operator的公司。看起来脸红。实际上我使用的是2.1.5。所以我将忙于重构。谢谢
return {
...state,
{
expanded: {
...state.expanded,
{
clients: !state.expanded.clients
}
}
}
};