0

In my nextjs page I have the following hook (generated by using graphql-codegen) that fetches a graphql query.

const { data, error, loading, fetchMore, refetch, variables } = useGetShortlistQuery({
  notifyOnNetworkStatusChange: true, // updates loading value
  defaultOptions: {
    variables: {
      offset: undefined,
      filterBy: undefined,
      sortBy: SortBy.RecentlyAdded,
      sortDirection: SortDirection.Desc,
    },
  },
});

This is the useGetShortlistQuery hook that is generated by graphql-codegen

export function useGetShortlistQuery(
  baseOptions?: Apollo.QueryHookOptions<GetShortlistQuery, GetShortlistQueryVariables>,
) {
  const options = { ...defaultOptions, ...baseOptions };
  return Apollo.useQuery<GetShortlistQuery, GetShortlistQueryVariables>(GetShortlistDocument, options);
}

my component is wrapped in a HOC to enable Apollo Client

export default withApollo({ ssr: true })(Index);

The withApollo HOC uses @apollo/client and the cache property of the apollo client is as follows.

cache: new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        getShortlist: {
          keyArgs: [],
          merge(existing: PaginatedProperties | undefined, incoming: PaginatedProperties): PaginatedProperties {
            return {
              ...incoming,
              properties: [...(existing?.properties || []), ...(incoming?.properties || [])],
            };
          },
        },
      },
    },
  },
}),

The problem I am having is that on this page I update the variables on the useGetShortlistQuery using refetch which, in turn, updates the data.

However, if I navigate to another page, then come back to this page using this component. It doesn't seem to retrigger the graphql query so returns the previous data.

mcclosa
  • 943
  • 7
  • 29
  • 59

1 Answers1

0

If you are using getStaticProps (or getServerSideProps) with pre rendered pages, it is a known behavior. It is due to optimisation by Next.js not re-rendering components between page navigations, with pages like [id].js.

The trick is to have a key on components that you want to see refreshing. You have multiple ways to do so. Having a different key on components tells React that it should be re-rendering the components, and thus will trigger again the hooks.

Practical example:

export const getStaticProps: GetStaticProps = async ({ params }) => {
  const data = getData() //something that fetches your data here

  return {
    props: {
      // some other data you want to return...
      // some unique value that will be on each page
      key: data.key
    },
  }
}

const MyPage: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = (props) => {
  <div key={props.key} />
}
Mentlegen
  • 988
  • 8
  • 11