1

Helo, i was develop web app using next js using react query for fetch api and now have a problem, when create local storage from _app.tsx base on url param

http://localhost:3000?token=123456789

and if i access it from index page, this local storage was not found

// app.tsx

import '../styles/globals.css';
import type { AppProps } from 'next/app';
import { Hydrate, QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';

function MyApp({ Component, pageProps }: AppProps) {
  const { isReady, query }: string | any = useRouter();
  const [queryClient] = useState(
    () =>
      new QueryClient({
        defaultOptions: {
          queries: {
            refetchOnWindowFocus: false,
            staleTime: 0,
            retry: false,
          },
        },
      })
  );

  useEffect(() => {
    if (isReady) {
      if (query.token) {
        console.info('token ', query.token);
        localStorage.setItem('token', query.token);
      } else {
        window.console.info('no token');
      }
      console.info('current token ', window.localStorage.getItem('token'));
    }
  }, [isReady]);

  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
        <Component {...pageProps} />
      </Hydrate>
      <ReactQueryDevtools />
    </QueryClientProvider>
  );
}

export default MyApp;

and below when i try to access token from local storage it was not found

  const { data, error, isFetching } = useQuery('event_list', () =>
    getEventList({
      token: window.localStorage.getItem('token') || null,
      query: {
        order_start: 'desc',
      },
    })
  );

1 Answer 1

1

Since you render your page even if isReady is false, the query will likely fire off once before the effect that sets the localStorage item kicks in. Since the token is not a dependency to the query, it won't refetch if the token changes.

What you can do is:

  • not render your app if isReady is false / you have no token, but that will likely disable SSR altogether.
  • put the token in react context, access it in your query and put it into the query key. That will make sure your query re-fetches when the token changes. You can also disable the query while it has no token:
const token = useTokenFromContext()
const query = useQuery(
  ['event_list', token],
  () => getEventList(token),
  {
    enabled: !!token
  }
)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.