创建NGRX Store时触发Cannot assign to read only property等报错咨询
报错原因
- 核心问题是你将Angular内部的
TemplateRef对象存入了NGRX Store,违背了NGRX的设计规则,也触发了内置的不可变校验机制:- NGRX默认开启严格的不可变运行时检查,所有存入Store的数据(包括你传入的
extArr数组、数组内的TemplateRef实例)都会被自动冻结(Object.freeze),不允许后续修改 TemplateRef是Angular视图体系的内部对象,生命周期和组件视图强绑定,Angular运行时会动态修改它的内部属性(比如你报错里提到的incompleteFirstPass、数组索引属性等),被冻结后修改就会抛出只读属性的报错
- NGRX默认开启严格的不可变运行时检查,所有存入Store的数据(包括你传入的
- 额外说明:你虽然对state做了结构拷贝,但
arrStart: extArr是直接赋值引用,并没有对数组本身做深拷贝,就算你做了深拷贝,TemplateRef这种非纯数据的对象被冻结后依然会报错,和state拷贝操作无关。
解决方法
推荐方案(符合NGRX设计规范)
不要将TemplateRef这类视图相关的非序列化对象存入Store,只在Store中存储纯数据标识:
- 你需要存储的是模板的类型、配置等可序列化的纯数据,比如
[{type: 'input'}, {type: 'textarea'}] - 在组件中维护
TemplateRef和标识的映射关系,从Store拿到数据后,再匹配对应的TemplateRef做渲染即可。
临时兼容方案(不推荐,会丢失不可变校验能力)
如果业务场景必须要存TemplateRef到Store,可以关闭NGRX的不可变运行时检查,在根模块导入StoreModule时修改配置:
StoreModule.forRoot(reducers, { runtimeChecks: { // 关闭state和action的不可变校验 strictStateImmutability: false, strictActionImmutability: false, } })
调整配置后重新运行项目即可消除报错,但缺失不可变校验后你需要自行保证所有state操作都符合不可变原则,避免出现其他隐性问题。
内容的提问来源于stack exchange,提问作者IRainbovvI
相关产品推荐
相关产品推荐

