Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

fix: unref() a ref.value should give the original object (by reference) #560

Closed
joerideg opened this issue Sep 27, 2021 · 3 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@joerideg
Copy link

🐛 The bug
When one assigns an object to a Ref.value it is made reactive and the Ref will hold a Proxy object (not the original one). using unref or toRaw one is supposed to be able to retrieve the original object assigned. This is useful when retrieving some big class instance from a third party for example to be used in the template.
https://v3.vuejs.org/api/refs-api.html
https://v3.vuejs.org/api/basic-reactivity.html#reactive

It seems that when we use one of the server side executed functions like useFetch or useAsync or onServerPrefetch, incombination with ssrRef as described in the docs, we do not get the same object by reference, even though we do get a 'copy' of the object.

🛠️ To reproduce

  1. Go to https://stackblitz.com/edit/nuxt-starter-hpgbfl?devtoolsheight=33&file=pages/index.vue
  2. Open the dev tools in your browser to see the console.
  3. Notice that the unreffed value of the ref is not equal to the original value when using any of the server side executed functions or ssrRef, but it is when doing the normal client side assignment.

🌈 Expected behaviour
The docs on 'ref' indicate that unwrapping the ref should give you the original object, somehow assigning to the ref.value in useFetch, onServerPrefetch, useAsync/ or using ssrRefs does give you a copy, but not the original object (the reference is not equal). I would expect the server-side executed functions to keep the original object. The normal nuxt hooks like asyncData or fetch do keep the original object as well.

ℹ️ Additional context
Could it be that this is because we are stringifying the object value to send it to the client?

@andrzejewsky
Copy link
Contributor

hey, @joerideg actually you can't really make them equals as ssrRef returns a proxied version of the given object. I know it can be possible with a regular ref but it works In a different way. A standard ref keeps just a state in the context of the caller without sharing anything between the browser and the server.

Using ssrRef gives you a way to create a reactive state as well as keeping values generated on the server also in the browser and for that reason, Nuxt is using proxies - it tracks all the changes you made (including nesting), then assign everything properly in the browser environment during hydration.

However, if we could refactor a bit proxying and get rid of that recursion: https://github.com/nuxt-community/composition-api/blob/main/src/runtime/composables/ssr-ref.ts#L108-L109 it could be possible, but I'm not sure if that won't break tracking/hydration (CC: @danielroe)

Note:
@joerideg Please look at this PR: #561 - this is something I came across recently, it solves a similar issue, I also didn't know why I'm getting an error and turns out the instances are different and built-in constructors loses their context (proxy limitations)

@joerideg
Copy link
Author

Thanks for looking into this @andrzejewsky and the explanation! I think your PR will fix my particular problem.

@danielroe
Copy link
Member

closed in #561

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants