我如何处理 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/