You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:01:06