The object type is not equal to the original object after unref
Vue version
3.2.37
Link to minimal reproduction
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.
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.
@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
. 😄
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.
@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.
ref()
appliesreactive()
to any object you pass to it docsreactive()
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.