Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: computed property hydration doesn't work with useFetch #207

Closed
andrzejewsky opened this issue Aug 17, 2020 · 7 comments
Closed

fix: computed property hydration doesn't work with useFetch #207

andrzejewsky opened this issue Aug 17, 2020 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@andrzejewsky
Copy link
Contributor

πŸ› The bug
The computed property it's not being hydrated properly because computed is readonly, so when we return that property in the setup (along with useFetch) it will cause a mismatch as nuxt wasn't able to assign the value

πŸ› οΈ To reproduce
Steps to reproduce the behavior:

const posts = ref(null);
const allPosts = computed(() => posts.value);

useFetch(async () => {
  posts.value  = ....
})

return { allPosts }; // that can't be hydrated

DEMO: https://codesandbox.io/s/sweet-leftpad-kdhl1

ℹ️ Additional context
I think this line is responsible for this: https://github.com/nuxt-community/composition-api/blob/main/src/fetch.ts#L266 - it needs somehow distinguish what kind of property we have and figure out what to do if it's computed.

@andrzejewsky andrzejewsky added the bug Something isn't working label Aug 17, 2020
@danielroe
Copy link
Member

See #19 for some context - and vuejs/composition-api#445 for a potential solution...

@danielroe
Copy link
Member

For a temporary workaround, try returning posts from the setup function too...

@andrzejewsky
Copy link
Contributor Author

andrzejewsky commented Aug 18, 2020

For a temporary workaround, try returning posts from the setup function too...

that totally won't work... posts is just example, we have more complex computed properties in the setup, so seems like this module is not ready to use, it will work only with simple refs. I've been even trying to solve it in nuxt itself but it's not so easy..

@danielroe
Copy link
Member

danielroe commented Aug 18, 2020

@andrzejewsky Sorry that didn't work for you as a workaround.

The issue is that the fetch mechanism in Nuxt isn't really designed for the Composition API. It's designed to only overwrite what is on the component instance. But with a Composition API workflow, you might have lots of things that aren't on the instance. So useFetch won't work for the kind of complex use-case you're thinking of - at least until Nuxt 3 comes out.

However, there are a lot of alternative approaches that do work right now. For example, you could use something like useStatic or useAsync. Or you could use your own mechanism - like defining posts as an ssrRef and running your own serverPrefetch. Take a look at the docs and feel do free to get in touch on Discord if you have any questions.

For example:

const posts = ssrRef(null);
const allPosts = computed(() => posts.value);

serverPrefetch(() => {
  posts.value  = ....
})

return { allPosts }; // this should work :-)

I'm closing this as an issue because it's a limitation of the way fetch works rather than a bug, but I appreciate it's frustrating that it didn't work for you - and do feel free to open a new one if you encounter any other issues!

@andrzejewsky
Copy link
Contributor Author

@danielroe it's totally understandable, I went through the code and I know what you mean, also I spent hours of thinking about how to solve that as was considering a PR with fixing this, but it's tough as there is no way to make computed assignable. In vue3 we have effects so it's somehow possible, I think we just have to wait - thanks for your help!

@Sara2009
Copy link

πŸ› The bug
The computed property it's not being hydrated properly because computed is readonly, so when we return that property in the setup (along with useFetch) it will cause a mismatch as nuxt wasn't able to assign the value

πŸ› οΈ To reproduce
Steps to reproduce the behavior:

const posts = ref(null);
const allPosts = computed(() => posts.value);

useFetch(async () => {
  posts.value  = ....
})

return { allPosts }; // that can't be hydrated

DEMO: https://codesandbox.io/s/sweet-leftpad-kdhl1

ℹ️ Additional context
I think this line is responsible for this: https://github.com/nuxt-community/composition-api/blob/main/src/fetch.ts#L266 - it needs somehow distinguish what kind of property we have and figure out what to do if it's computed.

I found this works. It is a right solution?

const posts = ref(null);

// writable 
// function computed<T>(options: { get: () => T; set: (value: T) => void }): Ref<T>
const allPosts = computed({
  get: () => posts.value,
  set: val => { allPosts.value = val; }, 
});

useFetch(async () => {
  posts.value  = ....
})

return { allPosts }; // that can't be hydrated

jtc42 pushed a commit to renalreg/ukrdc-nuxt that referenced this issue May 19, 2021
@danielroe
Copy link
Member

@Sara2009 Yes, it looks like that works πŸ‘

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

No branches or pull requests

3 participants