问题描述
Maximum call stack size exceeded
复现步骤
[复现问题的步骤]
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
补充信息
[可选]
可能是循环引用没处理好
欢迎提交 Issue~
如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏
如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。
Good luck and happy coding~
@luckyadam
@neewbee 来发一个完整的可运行的 demo,hzlhu.[email protected]
@nanjingboy https://github.com/neewbee/taro-mobx-issue-1991
@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
我找到了一种解决方法:
我是用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


拿到root你就可以该干嘛干嘛啦
Most helpful comment
mobx官网提供的组合store在小程序里行不通,为了避免在小程序里循环引用的问题,我们可以访问getRootStore方法来获取this.rootStore,而不是直接this.rootStore=this
拿到root你就可以该干嘛干嘛啦