vue-3-reactivity icon indicating copy to clipboard operation
vue-3-reactivity copied to clipboard

Cyclic Dependencies Possible Improvement For Ref

Open BorislavBorisov22 opened this issue 3 years ago • 1 comments

Currently the setter for reactive objects makes a check to see if new value is different from old value and only then triggers dep effects, which in some cases of cyclic dependencies might save us from a maximum call stack size exceeded error. But on the setter of ref objects we don't have that check and the example code below causes a max call stack size error:

effect(() => {
  console.log(a.value);
  b.value = 1;
});

effect(() => {
  console.log(b.value);
  a.value = 1;
});

Adding pretty much the same check as in reactive can save us from such cases:

export function ref(raw) {
  const r = {
    get value() {
      track(r, 'value');
      return raw;
    },
    set value(newValue) {
      const oldValue = raw;
      raw = newValue;
      if (oldValue !== raw) {
        trigger(r, 'value');
      }
    }
  };

  return r;
}

BorislavBorisov22 avatar Apr 19 '21 20:04 BorislavBorisov22

I second this.

Actually, for ref.js, I accidentally exchanged the position of two effect calls, ie, instead of:

effect(() => {
	salePrice.value = product.price * 0.9
})

effect(() => {
	total = salePrice.value * product.quantity
})

I wrote

effect(() => {
	total = salePrice.value * product.quantity
})

effect(() => {
	salePrice.value = product.price * 0.9
})

And I get max stack error (cyclic dependency): RangeError: Maximum call stack size exceeded

johnmiroki avatar Nov 29 '21 07:11 johnmiroki