I'm trying to implement a CRUD application using Apollo Client using nextJS and the serverless Framework as GraphQL backend. Is there any way to prevent unnecessary automatic refetch during app navigation using the cache?
For instance, I'm creating a new record with a mutation, adding refetchQueries will refresh the cache, but assuming the user is navigating to another view and then coming back to the view using useQuery
hook, the data will be fetched again, but it's supposed being already in the cache.
Here's my ApolloClient configuration:
import {ApolloClient} from 'apollo-client'
import {InMemoryCache, NormalizedCacheObject} from 'apollo-cache-inmemory'
import {createHttpLink, HttpLink} from 'apollo-link-http'
import {default as fetch} from 'isomorphic-unfetch'
import {config} from '~config'
const {IS_SERVER} = config
import {getToken} from '~security'
const token = getToken()
import {setContext} from 'apollo-link-context'
const authLink = setContext((_, {headers}) => {
return {
headers: {
...headers,
Authorization: token && `Bearer ${token}`,
}
}
})
const httpLink = createHttpLink({
uri: 'http://localhost:4000/graphql',
fetch
})
let apolloClient: ApolloClient<NormalizedCacheObject> | null = null
const create = (initialState = {}): ApolloClient<NormalizedCacheObject> => {
const httpLinkConfig: HttpLink.Options = {
uri: 'http://localhost:4000/graphql',
credentials: 'same-origin'
}
if (!IS_SERVER) {
httpLinkConfig.fetch = fetch;
}
return new ApolloClient({
connectToDevTools: !IS_SERVER,
ssrMode: IS_SERVER,
link: authLink.concat(httpLink),
cache: new InMemoryCache().restore(initialState)
})
}
export const initApollo = (initialState = {}): ApolloClient<NormalizedCacheObject> => {
if (!IS_SERVER) {
return create(initialState)
}
if (!apolloClient) {
apolloClient = create(initialState)
}
return apolloClient
}
Actually I found the solution to this issue after reading my config file.
Here's my _app.tsx
file:
I realized that I was rendering calling initApollo()
in the render of App, which ended in recreating an Apollo Client every time the location was changing.
Importing directly client
from the apollo definition prevents against recreating a new client at location change.
// apollo config file
export const client = initApollo()
import React from 'react'
import App from 'next/app'
import {client} from '~apollo'
import {ApolloProvider} from '@apollo/react-hooks'
import {Provider} from 'react-redux'
import {ConnectedRouter} from 'connected-next-router'
import {store} from '~store'
interface AppProps {
ctx: any,
Component: any
}
class Application extends App<AppProps> {
static async getInitialProps(props: AppProps) {
const {Component, ctx} = props
const pageProps = Component.getInitialProps ? await Component.getInitialProps(ctx) : {}
return {pageProps}
}
render = () => {
const {Component, pageProps} = this.props
return (
<ApolloProvider client={client}>
<Provider store={store}>
<ConnectedRouter>
<Component {...pageProps} />
</ConnectedRouter>
</Provider>
</ApolloProvider>
)
}
}
export default Application
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With