T
TanStack•3y ago
foreign-sapphire

Unsure if PersistQueryClientProvider is working with Next.js

Here is the code for my _app.js file:

function MyApp({ Component, pageProps }) {
const router = useRouter()
const [supabaseClient] = useState(() => createBrowserSupabaseClient())
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
cacheTime: 1000 * 60 * 60 * 24 // 24 hours
}
}
}))
let persister = useRef(null)



useEffect(() => {
const handleRouteChangeStart = () => {
NProgress.start()
}

const handleRouteChangeComplete = (url) => {
NProgress.done()
}

router.events.on('routeChangeStart', handleRouteChangeStart)
router.events.on('routeChangeComplete', handleRouteChangeComplete)
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart)
router.events.off('routeChangeComplete', handleRouteChangeComplete)
}
}, [router])

if (typeof window !== 'undefined') {
persister = createSyncStoragePersister({
storage: window.sessionStorage
})
}



return (
<>
<PlausibleProvider domain="nesteek.com">
<SessionContextProvider supabaseClient={supabaseClient} initialSession={pageProps.initialSession}>
<PersistQueryClientProvider client={queryClient} persistOptions={{ persister }}>
<Hydrate state={pageProps.dehydratedState}>
<ChakraProvider theme={theme}>
<Layout>
<Component {...pageProps} />
</Layout>
</ChakraProvider>
</Hydrate>
</PersistQueryClientProvider>
</SessionContextProvider>
</PlausibleProvider>
</>
)
}

function MyApp({ Component, pageProps }) {
const router = useRouter()
const [supabaseClient] = useState(() => createBrowserSupabaseClient())
const [queryClient] = useState(() => new QueryClient({
defaultOptions: {
queries: {
cacheTime: 1000 * 60 * 60 * 24 // 24 hours
}
}
}))
let persister = useRef(null)



useEffect(() => {
const handleRouteChangeStart = () => {
NProgress.start()
}

const handleRouteChangeComplete = (url) => {
NProgress.done()
}

router.events.on('routeChangeStart', handleRouteChangeStart)
router.events.on('routeChangeComplete', handleRouteChangeComplete)
return () => {
router.events.off('routeChangeStart', handleRouteChangeStart)
router.events.off('routeChangeComplete', handleRouteChangeComplete)
}
}, [router])

if (typeof window !== 'undefined') {
persister = createSyncStoragePersister({
storage: window.sessionStorage
})
}



return (
<>
<PlausibleProvider domain="nesteek.com">
<SessionContextProvider supabaseClient={supabaseClient} initialSession={pageProps.initialSession}>
<PersistQueryClientProvider client={queryClient} persistOptions={{ persister }}>
<Hydrate state={pageProps.dehydratedState}>
<ChakraProvider theme={theme}>
<Layout>
<Component {...pageProps} />
</Layout>
</ChakraProvider>
</Hydrate>
</PersistQueryClientProvider>
</SessionContextProvider>
</PlausibleProvider>
</>
)
}
7 Replies
foreign-sapphire
foreign-sapphireOP•3y ago
I use the queryClient that I think I have persisted inside of a step in within a multi-step form. Here is how I use the queryClient to set defaultValues for this form:
const goHome = () => {
queryClient.setQueryData(['newListing'], null)
queryClient.setQueryData(['incompleteListing'], null)
queryClient.invalidateQueries('allMyListings')
router.push('/')
}

const exit = () => {
queryClient.setQueryData(['newListing'], null)
queryClient.setQueryData(['incompleteListing'], null)
queryClient.invalidateQueries('allMyListings')
router.push('/my-account/my-listings')
}


useEffect(() => {
const newListingData = queryClient.getQueryData(['newListing'])
const incompleteListingData = queryClient.getQueryData(['incompleteListing'])

if (newListingData) {
setValue('about', newListingData?.description)
} else if (incompleteListingData) {
setValue('about', incompleteListingData?.description)
} else {
setValue('about', null)
}
}, [setValue, queryClient])
const goHome = () => {
queryClient.setQueryData(['newListing'], null)
queryClient.setQueryData(['incompleteListing'], null)
queryClient.invalidateQueries('allMyListings')
router.push('/')
}

const exit = () => {
queryClient.setQueryData(['newListing'], null)
queryClient.setQueryData(['incompleteListing'], null)
queryClient.invalidateQueries('allMyListings')
router.push('/my-account/my-listings')
}


useEffect(() => {
const newListingData = queryClient.getQueryData(['newListing'])
const incompleteListingData = queryClient.getQueryData(['incompleteListing'])

if (newListingData) {
setValue('about', newListingData?.description)
} else if (incompleteListingData) {
setValue('about', incompleteListingData?.description)
} else {
setValue('about', null)
}
}, [setValue, queryClient])
The queryData from getQueryData doesn't persist on refresh and undefined is returned instead. I don't believe I have set up the PersistQueryClientProvider correctly with Next.js and would like some assistance in ensuring that I do.
absent-sapphire
absent-sapphire•3y ago
Can you try putting the persister creation in state as well? A reproduction would be good
foreign-sapphire
foreign-sapphireOP•3y ago
Sure. I will upload a reproduction in a bit
foreign-sapphire
foreign-sapphireOP•3y ago
persistQueryClientProvider setup
CodeSandbox is an online editor tailored for web applications.
absent-sapphire
absent-sapphire•3y ago
well the TestPage still renders while we're restoring the cache from localstorage, so the effect will also run. We've made sure that useQuery respects that, but if you manually read from the cache, you have to keep that in mind as well. You can read from useIsRestoring() to see if we're in the process of restoring and either not render your component or delay the effect accordingly.
foreign-sapphire
foreign-sapphireOP•3y ago
Understood. Thank you for your assistance.

Did you find this page helpful?