Subscribe on changes!

The object type is not equal to the original object after unref

avatar
Jul 26th 2022

Vue version

3.2.37

Link to minimal reproduction

https://sfc.vuejs.org/#eNqNUlFOwzAMvYqVn3YSSwSf0TqJE+wC+ek6t3RqkyhxAGnqDTgSd+IKuM02EEOISlVj+/nZry8n8ei9fE4otNjEJvSeICIlvzW2H70LBCcI2N5BsssH2xYbggna4EYouLMwFsDYxtlI4PZHqOA0p2oN98ZOxl5roe96Ww8MYKqSoatLaSHHw+4LsWTKSwsDM9QNKAfXlcWPjuK84HeOqprXWYFS0DnS0NZDxI/3N3z1LAEPGigkzNtnWWW5gmqb1/9rmmRttxNlzWtO/PLAXSKfSC/n/PxCwb/nJsvSH/7PwNCNyraxYRwQjn6oCXOkrqG4E9nO9Vh7eYzOsuGLTnMuRCN0Vj7n2Nc5NuKJyEetVGyb+Zoco3ShU3ySIVnqR5QYx/U+uJeIgYmNmCnY9UlMnxN90ZQ=

Steps to reproduce

Please open your browser console to view the output

What is expected?

I'm not quite sure if this is expected.

Common sense dictates that when an object is generated as an instance of ref as an argument to ref, and then unpacked by unref, the result of the unpacking should be the same as the original object. But the performance is not consistent.

What is actually happening?

Unwrapping with unref is not consistent with the original object.

System Info

System:
    OS: macOS 12.2
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 454.80 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: 1.22.18 - ~/.nvm/versions/node/v14.18.3/bin/yarn
    npm: 8.13.2 - ~/.nvm/versions/node/v16.15.1/bin/npm
  Browsers:
    Chrome: 103.0.5060.134
    Safari: 15.3
  npmPackages:
    vue: workspace:* => 3.2.37

Any additional comments?

I understand that the arguments to the ref will be toReactive, as the _value attribute of the ref, and when the arguments are objects, then they will be converted to responsive objects, which is written in the documentation.

When using unref, its source code only returns the value attribute, which results in a responsive object being returned out and therefore inconsistent with the original object.

avatar
Jul 26th 2022

Sorry if this is expected behaviour, I will close this issue, otherwise I can mention PR to fix it.

avatar
Jul 26th 2022

Yes, this is expected behavior.

When a ref contains an object, getting its inner value will give you the reactive proxy, not the original object.

You are confusing unref(), which gives you the inner value of a ref, with toRaw(), which gives you the raw original object for a reactive proxy.

avatar
Jul 26th 2022

@LinusBorg I meant unref(ref(obj)) ! == obj This doesn't seem to make common sense in life. If this is what is expected here, I personally feel that unref might be more realistically renamed to getRefValue. 😄

avatar
Jul 26th 2022

It does make sense if you are aware that Vue uses ES6 Proxies for its reactivity, and a proxy object is not identical to its target object.

avatar
Jul 26th 2022

@LinusBorg Yes, I'm working towards a deeper understanding of reactivity., I create a ref instance by calling the ref method and then call unref to get something other than the original object, which is a bit confusing, sorry, maybe I'm just not thinking straight.

avatar
Jul 26th 2022
  • ref() applies reactive() to any object you pass to it docs
  • reactive() returns a reactive proxy, not the original docs
  • A proxy is not identical to the nonreactive original value that it represents.

The returned object and its nested objects are wrapped with ES Proxy and not equal to the original objects.** It is recommended to work exclusively with the reactive proxy and avoid relying on the original object.**

  • This identity hazard is also mentioned and explained here

The returned proxy from reactive(), although behaving just like the original, has a different identity if we compare it to the original using the === operator.

avatar
Jul 26th 2022

Thanks.