Taro: [mobx] Maximum call stack size exceeded

Created on 19 Jan 2019  ·  22Comments  ·  Source: NervJS/taro

问题描述
Maximum call stack size exceeded

复现步骤
[复现问题的步骤]

  1. 打开 mobx 项目 进入 store 文件夹, 添加以下文件

Root.js

import { observable } from 'mobx';
import CounterStore from './Counter';
import DummyStore from './Dummy';

export default class RootStore {
  @observable counter = 1;
  constructor() {
    this.counterStore = new CounterStore(this);
    this.dummyStore = new DummyStore(this);
  }
}

DummyStore.js

import { observable } from 'mobx';

class Dummy {
  constructor(rootStore) {
    this.rootStore = rootStore;
  }
  @observable counter = 1;
  increment() {
    this.counter++;
  }
  decrement() {
    this.counter--;
  }
  incrementRootStoreCounter() {
    this.rootStore.counter++;
  }
  decrementRootStoreCounter() {
    this.rootStore.counter--;
  }
  incrementAsync() {
    setTimeout(() => {
      this.counter++;
    }, 1000);
  }
}

export default Dummy;

CounterStore.js

import { observable } from 'mobx';

class CounterStore {
  constructor(rootStore) {
    this.rootStore = rootStore;
  }
  @observable counter = 1;
  increment() {
    this.counter++;
  }
  decrement() {
    this.counter--;
  }
  incrementRootStoreCounter() {
    this.rootStore.counter++;
  }
  decrementRootStoreCounter() {
    this.rootStore.counter--;
  }
  incrementAsync() {
    setTimeout(() => {
      this.counter++;
    }, 1000);
  }
}

export default CounterStore;

修改 app.jsx

import RootStore from './store/Root';
const rootStore = new RootStore();
const counterStore = rootStore.counterStore;
const dummyStore = rootStore.dummyStore;
const store = {
  counterStore,dummyStore
};

期望行为
不报错

报错信息

VM625:1 thirdScriptError 
 sdk uncaught third Error 
 Maximum call stack size exceeded 
 RangeError: Maximum call stack size exceeded
    at s (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820473)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820718)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)
    at e (http://127.0.0.1:10547/appservice/__dev__/WAService.js:1:820939)

系统信息

Taro v1.2 及以上版本已添加 taro info 命令,方便大家查看系统及依赖信息,运行该命令后将结果贴下面即可。

👽 Taro v1.2.4


  Taro CLI 1.2.4 environment info:
    System:
      OS: Windows 10
    Binaries:
      Node: 8.11.1 - C:\Program Files\nodejs\node.EXE
      npm: 5.6.0 - C:\Program Files\nodejs\npm.CMD

补充信息
[可选]
可能是循环引用没处理好

Most helpful comment

mobx官网提供的组合store在小程序里行不通,为了避免在小程序里循环引用的问题,我们可以访问getRootStore方法来获取this.rootStore,而不是直接this.rootStore=this

image

image

拿到root你就可以该干嘛干嘛啦

All 22 comments

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@luckyadam

@neewbee 来发一个完整的可运行的 demo,hzlhu.[email protected]

@nanjingboy 用邮件传代码 zip 包会被 Gmail 拦截。我就不传了

@neewbee 这是因为你的 store 中存在循环引用的问题:RootStore 中引用了 CounterStore 和 Dummy,然后在 CounterStore 和 Dummy 中又引用了 RootStore,如此在进行序列化的时候导致了死循环。

@nanjingboy 这个我在 web 项目里面是可以的。另外,请参考:

https://mobx.js.org/best/store.html#combining-multiple-stores

@nanjingboy 需要 web 端 rootstore 用例源代码晚些时候可以给你。

@neewbee 不需要给了,https://github.com/neewbee/taro-mobx-issue-1991 这个例子我运行过了,Web OK 的

@nanjingboy 那这个循环引用是 Taro 的问题还是微信的呢?

@neewbee taro 在小程序中对 props 进行序列化的用的是 JSON.stringify,这个是 JSON.stringify 自身的问题。

@nanjingboy 那我现在是不是暂时没法用这种方式了

@neewbee 是的

我也是这个问题 原来是mobx 引起的

@nanjingboy 那我现在是不是暂时没法用这种方式了

请教一下你最后怎么解决的?

@atyvee 目前是避免循环引用

@atyvee 目前是避免循环引用
嗯嗯 我现在想的是把store里面的耦合去掉, 再视图里面再操作多个store

我找到了一种解决方法:

Uploading WX20190516-200952@<br />
<img width="626" alt="WX20190516-201113@2x" src="https://user-images.githubusercontent.com/38548475/57852821-c9194180-7816-11e9-9589-6b38d9e121c2.png"><br />
2x.png…

我是用ts写的 省略了导入导出和类型申明

//rootStore
export class RootStore {
counter = new CounterStore()
test = new TestStore()

getRoot() {
return this
}
}

const rootStore = new RootStore()

rootStore.counter.root = () => rootStore
rootStore.test.root = () => rootStore

//countStore
export class CounterStore {
@observable
counter: number = 0

root : () => IRootStore

@action
increment = (number: number = 1) => {
const root = this.root()
console.log(root.test.counter)
this.counter += number
}

@action
decrement = (number: number = 1) => {
this.counter -= number
}
}

//testStore
export class TestStore {
@observable
counter: number = 0

root : () => IRootStore

@action
increment = (number: number = 1) => {
this.counter += number
}

@action
decrement = (number: number = 1) => {
this.counter -= number
}
}

@neewbee taro 在小程序中对 props 进行序列化的用的是 JSON.stringify,这个是 JSON.stringify 自身的问题。

@nanjingboy 对 props 序列化?现在貌似没有做这一步,能指出一下代码么

@Chen-jj 是的,小程序对 props 序列化的实现,具体代码有空给你找一下

mobx官网提供的组合store在小程序里行不通,为了避免在小程序里循环引用的问题,我们可以访问getRootStore方法来获取this.rootStore,而不是直接this.rootStore=this

image

image

拿到root你就可以该干嘛干嘛啦

Was this page helpful?
0 / 5 - 0 ratings