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

rc.5 breaks hydrating useFetch data #14318

Closed
johannschopplich opened this issue Jul 14, 2022 · 15 comments
Closed

rc.5 breaks hydrating useFetch data #14318

johannschopplich opened this issue Jul 14, 2022 · 15 comments

Comments

@johannschopplich
Copy link
Contributor

johannschopplich commented Jul 14, 2022

Environment

Reproduction

ℹ️ Edit: See minimal reproductions from @KoenCa in the comments below.

Reproduction with nuxt-kql module

Repo (RC 5): https://github.com/johannschopplich/kirby-nuxt-starterkit/tree/feat/nuxt-3-rc.5
👉 Live demo of this repo: https://superlative-gelato-9c9293.netlify.app (Inspect the bug in the console)

Repo (RC 4): https://github.com/johannschopplich/kirby-nuxt-starterkit
👉 Live demo of this repo: https://kirby-nuxt-starterkit.netlify.app

Describe the bug

Server-side fetched data can't be hydrated in the client. A custom key is passed to useFetch (the same on client & server), but on the client the data for the same key seems not be able to be fetchable.

With disabled build minification, the console (client) throws:

TypeError: data.value is null

In rc.4, everything worked correctly.

Additional context

No response

Logs

👀 View the console error
TypeError: data.value is null
    NuxtJS 63
        setup
        callWithErrorHandling
        setupStatefulComponent
        setupComponent
        mountComponent
        hydrateNode
        hydrateSuspense
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrateChildren
        hydrateElement
        hydrateNode
        hydrateChildren
        hydrateFragment
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrateSuspense
        hydrateNode
        hydrateSubTree
        componentUpdateFn
        run
        update
        setupRenderEffect
        mountComponent
        hydrateNode
        hydrate
        mount
        mount
        initApp
        async*
entry-d9af1809.mjs:1091:13
@johannschopplich johannschopplich changed the title rc.5 breaks server-side rendered data with TypeError: data.value is null rc.5 breaks hydrating useFetch data Jul 14, 2022
@KoenCa
Copy link

KoenCa commented Jul 14, 2022

I also ran into this problem. useFetch seems to be broken in some way. I have code like in this example: https://v3.nuxtjs.org/guide/features/data-fetching/#using-async-setup .

After upgrading to rc. 5 it breaks. The first useFetch runs again on the client and the second useFetch doesn't run. Rolling back to rc. 4 fixes it.

@KoenCa
Copy link

KoenCa commented Jul 14, 2022

I made two Stackblitz projects to reproduce. They both use the example I mentioned:

The only difference is the Nuxt version.

@johannschopplich
Copy link
Contributor Author

@KoenCa Thanks! I've edited the initial post to link to your examples.

@WamiqM
Copy link

WamiqM commented Jul 14, 2022

I have got a similar problem after upgrading from RC. 4 to RC. 5
useFetch runs only for the first request. Subsequent useFetch requests return a copy of the first request's data.

Following are the reproduction projects for RC. 4 and RC. 5 similar to my current setup.

@pi0 pi0 added bug and removed pending triage labels Jul 14, 2022
@pi0
Copy link
Member

pi0 commented Jul 14, 2022

Thanks for making reproduction and detailed issues. With RC.5, for the default key instead of generating a hash from dynamic url passed to the useFetch, we auto-generate the key based on static code location where useAyncData, useFetch or useState are used. (#4955)


A hash collision is initial provided reproduction was happening (app.vue-331 and app.vue-385 both resolving to same 875093775). It is fixed in the latest ohash library using secure SHA256. To fix, you can upgrade lockfile:

npx nuxi@latest upgrade --force

@WamiqM With your reproduction, there is another edge case BTW that is different from hash collision. Since now key is based on static code location of useAsyncData, all 3 composables are depending on same key. You need to compute the key by yourself. Otherwise it works but each call updates all 3.

(Docs need to be improved)

Example:

import { hash } from 'ohash'

export const apiFetch = (url: string, fetchOptions: any = {}) => {
  return useFetch(url, {
    baseURL: 'https://api.github.com/',
    key: hash(['api-fetch', url, fetchOptions]), // <---
    ...fetchOptions,
    headers: {
      ...fetchOptions.headers,
    },
  });
};

Note: You can use any custom key instead of hashing input or manually pass as 3rd argument. Hash is just probably safest

Note: For nested fetch composables, I would recommend to switch to useState with explicit key and $fetch.

@pi0 pi0 pinned this issue Jul 14, 2022
@WamiqM
Copy link

WamiqM commented Jul 14, 2022

@pi0 providing/computing the key solves my issue. Thank you for explaining and for your recommendation. 👍

@johannschopplich
Copy link
Contributor Author

johannschopplich commented Jul 14, 2022

@pi0 Thanks for the thorough investigation. Unfortunately, my useFetch calls still fail. It's not that simple to reduce the error further. Unique keys are being used (since yesterday even).

It seems to break on Netlify; local preview is working:

Repo (RC 5, where it is breaking): https://github.com/johannschopplich/kirby-nuxt-starterkit/tree/feat/nuxt-3-rc.5
👉 Live demo of this repo: https://superlative-gelato-9c9293.netlify.app/ (Inspect the bug in the console)

Repo (RC 4): https://github.com/johannschopplich/kirby-nuxt-starterkit
👉 Live demo of this repo: https://kirby-nuxt-starterkit.netlify.app/

Would you mind opening the first Netlify build to see the error in the console? Seems like a second useFetch call just returns null.

@KoenCa
Copy link

KoenCa commented Jul 14, 2022

@pi0 Thanks for the explanation. I upgraded to rc. 5 and provided a unique key to all my useFetch calls, because I also use a custom composable for data fetching and now it works.

@johannschopplich
Copy link
Contributor Author

All right, seems like something is broken in my setup. Closing this for now. Thanks for all the insightful messages!

@pi0
Copy link
Member

pi0 commented Jul 18, 2022

Issues should be fixed in the latest RC.6 release.

@mlbonniec
Copy link

Hi, I'm using the release candidate 6, and I've got the same issue.
On production mode, data.value is null

@pi0
Copy link
Member

pi0 commented Jul 29, 2022

@mlbonniec Would you please open new issue with reproduction? 🙏

@mlbonniec
Copy link

@mlbonniec Would you please open new issue with reproduction? 🙏

I can't reproduce the bug except on my project 😕

@pi0
Copy link
Member

pi0 commented Jul 29, 2022

Any code snippet of usage could also help in new issue. Can you please also try edge? (https://v3.nuxtjs.org/guide/going-further/edge-channel). We just pushed an improvement regarding key generation.

@mlbonniec
Copy link

I tried @pi0, and it didn't fix the problem. So I just opened a Github issue ^^
Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants