使用MobX时出现Maximum call stack size exceeded错误
解决MobX栈溢出问题的方案
可能的触发原因
- CSS.parse返回的结果是深层嵌套的复杂对象,MobX尝试将其完整转为可观察对象时,递归处理层级过多导致栈溢出
convertToRule的执行逻辑触发了MobX响应式循环:修改_rule状态→触发依赖该状态的effect→再次调用convertToRule修改状态,形成无限循环
具体修复步骤
1. 避免将CSS解析结果全量转为可观察对象
如果_rule不需要作为响应式状态,或者仅需部分属性响应,通过以下方式处理:
// 方案1:在MobX初始化时排除_rule的观察(以makeAutoObservable为例) constructor() { makeAutoObservable(this, { _rule: false // 禁止MobX对该属性做响应式处理 }) } // 方案2:仅浅观察_rule(只监控第一层属性变化) this._rule = observable.shallow(CSS.parse(this.theme.css)); // 方案3:直接存为普通对象(如果不需要响应式) this._rule = CSS.parse(this.theme.css);
2. 切断响应式循环
检查调用convertToRule的useEffect依赖数组,仅依赖数据源变量,避免依赖会被修改的_rule:
useEffect(() => { if (theme?.css && theme?.jsonStructure) { convertToRule(); } }, [theme.css, theme.jsonStructure]); // 只监听数据源变化,不监听_rule
3. 优化CSS库引入逻辑
把库引入移到模块顶部,避免每次调用函数都重复加载:
import CSS from 'css'; // 或const CSS = require('css'); 放在文件开头 convertToRule(): void { if (this.theme && this.theme.jsonStructure && this.theme.css) { const stylesheet = JSON.parse(this.theme.jsonStructure) as Reptile.Models.IThemesStyling[]; if (Array.isArray(stylesheet)) { this._rule = CSS.parse(this.theme.css); } else { this._rule = stylesheet; } } }
4. 截断CSS解析结果的嵌套层级(可选)
如果必须观察该对象,手动提取需要的属性,减少MobX递归处理的复杂度:
const parsedCss = CSS.parse(this.theme.css); // 仅保留业务需要的顶层属性,比如样式规则数组 this._rule = { rules: parsedCss.stylesheet?.rules || [] };
内容的提问来源于stack exchange,提问作者Joe Ellul-Turner
相关产品推荐
相关产品推荐

