我如何处理 MobX 中的循环引用?
How can I deal with circular references in MobX?
我有这个代码:
var root = {};
var left = {};
rootClass.left = left;
var right = {};
right.left = left;
left.right = right;
var o = observable(root);
right
有指向 left
的指针,left
有指向 right
的指针。
执行最后一行时出现此错误:
RangeError: Maximum call stack size exceeded
at _tryDefineProperty (vendor.bundle.js:91185)
at Function.Object.defineProperty (vendor.bundle.js:91141)
at addHiddenFinalProp (vendor.bundle.js:14605)
at asObservableObject (vendor.bundle.js:14122)
at Function.IObservableFactories.object (vendor.bundle.js:12329)
at deepEnhancer (vendor.bundle.js:13382)
at new ObservableValue (vendor.bundle.js:14280)
at defineObservableProperty (vendor.bundle.js:14163)
at defineObservablePropertyFromDescriptor (vendor.bundle.js:14143)
at extendObservableHelper (vendor.bundle.js:12207)
at extendObservable (vendor.bundle.js:12178)
at Function.IObservableFactories.object (vendor.bundle.js:12330)
at deepEnhancer (vendor.bundle.js:13382)
at new ObservableValue (vendor.bundle.js:14280)
at defineObservableProperty (vendor.bundle.js:14163)
如何处理 MobX 中的循环引用?
MobX 背后的想法是 Excel 电子表格。您需要考虑哪些数据可以导出,哪些不能导出。
如果您的对象具有带键的循环结构,则引用是派生数据的一个很好的例子。
你最终要做的只是将所有由 id 键控的对象存储在一个对象(或 MobX 映射)中。
接下来,不创建左右属性,而是将它们创建为计算的 getters 和 setters。
左右对象 ID 将存储在属性中(例如 leftId 和 rightid)。
getter 将通过查看根对象存储中的 leftId 简单地解析左或右。 setter 将简单地提供一种逻辑来将 id 存储在 leftId/rightId 属性 中,而不是存储整个对象。
observable({
id: nextId(), // progressive id for sample
name,
leftId: null, // variables to store the id in {$ref: 1}
rightId: null,
get left(){ // getters and setters
return allItems.has(this.leftId) ?
allItems.get(this.leftId) :
null
},
set left(item){
this.leftId = item ? item.id : null
},
get right(){
return allItems.has(this.rightId) ?
allItems.get(this.rightId) :
null
},
set right(item){
this.rightId = item ? item.id : null
},
})
整个Fiddle例子:https://jsfiddle.net/4ure5kak/2/
我有这个代码:
var root = {};
var left = {};
rootClass.left = left;
var right = {};
right.left = left;
left.right = right;
var o = observable(root);
right
有指向 left
的指针,left
有指向 right
的指针。
执行最后一行时出现此错误:
RangeError: Maximum call stack size exceeded at _tryDefineProperty (vendor.bundle.js:91185) at Function.Object.defineProperty (vendor.bundle.js:91141) at addHiddenFinalProp (vendor.bundle.js:14605) at asObservableObject (vendor.bundle.js:14122) at Function.IObservableFactories.object (vendor.bundle.js:12329) at deepEnhancer (vendor.bundle.js:13382) at new ObservableValue (vendor.bundle.js:14280) at defineObservableProperty (vendor.bundle.js:14163) at defineObservablePropertyFromDescriptor (vendor.bundle.js:14143) at extendObservableHelper (vendor.bundle.js:12207) at extendObservable (vendor.bundle.js:12178) at Function.IObservableFactories.object (vendor.bundle.js:12330) at deepEnhancer (vendor.bundle.js:13382) at new ObservableValue (vendor.bundle.js:14280) at defineObservableProperty (vendor.bundle.js:14163)
如何处理 MobX 中的循环引用?
MobX 背后的想法是 Excel 电子表格。您需要考虑哪些数据可以导出,哪些不能导出。
如果您的对象具有带键的循环结构,则引用是派生数据的一个很好的例子。
你最终要做的只是将所有由 id 键控的对象存储在一个对象(或 MobX 映射)中。
接下来,不创建左右属性,而是将它们创建为计算的 getters 和 setters。
左右对象 ID 将存储在属性中(例如 leftId 和 rightid)。
getter 将通过查看根对象存储中的 leftId 简单地解析左或右。 setter 将简单地提供一种逻辑来将 id 存储在 leftId/rightId 属性 中,而不是存储整个对象。
observable({
id: nextId(), // progressive id for sample
name,
leftId: null, // variables to store the id in {$ref: 1}
rightId: null,
get left(){ // getters and setters
return allItems.has(this.leftId) ?
allItems.get(this.leftId) :
null
},
set left(item){
this.leftId = item ? item.id : null
},
get right(){
return allItems.has(this.rightId) ?
allItems.get(this.rightId) :
null
},
set right(item){
this.rightId = item ? item.id : null
},
})
整个Fiddle例子:https://jsfiddle.net/4ure5kak/2/