首页 > 解决方案 > 在 NgRx 中填充状态期间不满足状态不变性

问题描述

我有一个从后端下载的对象数组,现在我想用它来填充我的状态变量。问题是对象有多个嵌套级别。

国家是——

const initialState: SummaryStateInterface = {
  summaryList: [], // Problem is only with this one. 
  editIndex: null,
  editItem: null,
  addingNew: false,
  modifications: false,
  isLoading: false,
}

SummaryStateInterface 是这样的:

export interface SummaryStateInterface {
  summaryList: Summary[] | null;
  editIndex: number | null;
  editItem: Summary | null;
  addingNew: boolean | null;
  modifications: boolean;
  isLoading: boolean;
}

总结模型是这样的:

export class Summary {
  @required()
  title: string;
  @required()    // these decorators are for form validation  
  text: string;
  @required()    // these decorators are for form validation
  focus: Focus[] = [];
  @prop()
  focusRef: DocumentReference[];
  seqNo: number;
  id: string;
}

Focus模型是这样的-

export class Focus {
  @required()
  name: string;
  seqNo: number;
  id: string;
}

将数据传递给此操作的效果是 -

    this.actions$.pipe(
      ofType(readSummaryAction),
      switchMap(() =>
        this.service.list$.pipe(
          map(list => {
            console.log('This is the list ', list);
            return readSummarySuccessAction({ list });
          }),
          catchError(() => of(readSummaryFailureAction())),
        ),
      ),
    ),
  );

我试图填充 summaryList 的减速器是这样的 -

  on(
    readSummarySuccessAction,
    (state, action): SummaryStateInterface => {
      const updatedSummaryList = [...state.summaryList].concat(
        JSON.parse(JSON.stringify(action.list)),
      );
      return {
        ...state,
        summaryList: updatedSummaryList,
        ),
      };
    },
  ),

为此操作传递的数据是 2 个项目的数组 (2) [{...}, {...}] 0: {title: "Resume", url: "resume", ionicIcon: "", customIcon: "./assets/投资组合.svg”,开放:假,...} 1:{title:“数据库”,url:“”,ionicIcon:“”,customIcon:“./assets/server.svg”,开放:假,...}长度: 2 原型:数组(0)

其中一项是 -

focus: Array(3)
0: {id: "focusId1", name: "Main", seqNo: 1}
1: {id: "focusId2", name: "CFD", seqNo: 2}
2: {id: "focusId3", seqNo: 4.5, name: "Web"}
length: 3
__proto__: Array(0)
focusRef: (3) [n, n, n] // Firebase document reference
id: "sum1"
seqNo: 2.5
text: "Versatile and detail-driven Mechanical Engineer with a wealth of experience and knowledge in the Thermal-Fluids area. "
title: "Professional Summary"

抛出的错误是 -

core.js:4197 ERROR TypeError: Cannot freeze
    at Function.freeze (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103583:12)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103586:40)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103586:40)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)

UnsubscriptionErrorImpl {消息:“取消订阅期间发生2个错误:↵1)TypeEr ...:无法添加属性0,对象不可扩展”,名称:“UnsubscriptionError”,错误:Array(2)}

core.js:4197 错误类型错误:无法分配给对象“[object Object]”的只读属性“__zone_symbol__state”

zone-evergreen.js:976 未捕获类型错误:无法添加属性 0,对象不可扩展

是否有可能得到一些反馈?
我愿意重组(扁平化)国家——但具体是什么以及如何,我不知道。

标签: angularreduxngrxngrx-effects

解决方案


Summary 类中的 focusRef 属性是一个 DocumentReference。不幸的是,无论出于何种原因,Firebase 中的 DocumentReference 字段都有循环引用。

本文讨论了循环引用主题: Firestore 引用创建“TypeError:将循环结构转换为 JSON”

我将这些引用 (ref) 转换为字符串 - 使用它们的路径属性 (ref.path)。

一旦字符串所有这些错误都消失了。如果有人能解释 core.js 的冻结如何工作,我会很高兴 - 它抛出以下错误 -

core.js:4197 ERROR TypeError: Cannot freeze
    at Function.freeze (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103583:12)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103586:40)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)
    at freeze (http://localhost:8101/vendor.js:103586:40)
    at http://localhost:8101/vendor.js:103603:17
    at Array.forEach (<anonymous>)

不相关但有用 检测对象 (x) 中的循环引用是:执行 JSON.parse(JSON.stringify(x))。此表达式将失败。


推荐阅读