skip to Main Content

I have a Next.js application where I use @tanstack/react-query@4 for state management and data fetching. I use it for authentication state via a custom useUser() hook that is used throughout the app, including in a nav bar component shared across all pages in a layout component. Let’s say I have two identical pages showing me the current user. When I first open my app, everything works fine as the data is shared between the page and the nav bar. Whether I enter page A or B, the observer count for the key ["user"] is 2. The weird thing is that when I navigate to another page and refetch the key, it seems to detach the key from the nav bar, and it stays un-updated (you can see that the observer count is 1). Any advice on how to keep those linked will help!

See in CodeSandbox

Screen Recording

2

Answers


  1. i think that you should pass a props to layout component in the _app page , the pages route provided by nextjs and components folder that we are using for stucturing our projects do not have the same config, that means tha data avaible inside pages will be avaible on your layouts only when you pass them as props , you can fetch the user inside a getStaticProps or Serversideprops (depends on your needs) in your page then the user will be avaible in pageProps inside the _app page, there you can pass your user to your layout as props

    Login or Signup to reply.
  2. The problem is you’re having an "unstable" QueryClient, as you just create it inside the App component:

    export default function App({ Component, pageProps }: AppProps) {
      const queryClient = new QueryClient()
    

    so every time App re-renders, you’ll get a new QueryClient. The QueryClient holds the QueryCache, so you throw away cached data, and attached observers etc.

    The solution is to keep the client stable, either by moving the instantiation out of the App component, or by putting it into state or an instance ref. For a nextJs application, moving it out of the component is not recommended because it means data might be shared between users when server-rendering. So, as in the docs, this is the solution:

    export default function App({ Component, pageProps }: AppProps) {
      const [queryClient] = useState(() => new QueryClient());
    

    Here’s a clone of your sandbox with the fixed version

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search