Creating an auth hook with Apollo

I am a huge fan of Apollo. I find their internal caching mechanisms to be a really great tool. One thing I found myself doing a lot was using my GetUser query in several components. In order to refactor this I went ahead and made a pretty standard hook useAuth. This hook will return either a user, if logged in, or undefined if not. Additionally, it also passes in the logoutUser function. The code looks like the following:

export function useAuth(fetchPolicy?: WatchQueryFetchPolicy) {
  const { data, error } = useQuery<GetUser>(GET_USER, {
    fetchPolicy: fetchPolicy ?? 'cache-first',
  })

  const [logoutUser, { client }] = useMutation<Logout>(LOGOUT_USER, {
    onCompleted: () => {
      client.clearStore()
    },
  })

  return {
    user: error !== undefined ? undefined : data?.me,
    logoutUser,
  }
}

Now, if a developer wants to access the currently authed user in any component, they can simply use the hook like so:

const { user } = useAuth()

One additional convenience parameters I added was the fetchPolicy. This enables the developer to determine the level of caching the query uses. You can read about the supported Apollo fetch policies here. By default, we use cache-first. The means, that Apollo is simply checking the cache for the user and if all the data is available, it won't make a network call to the backend.

If you knew for some reason that you would in fact like to bypass the local cache, you can pass in something like:

const { user } = useAuth('network-only')

This will now execute the GetUser query against the GraphQL service and store the new values in the cache.

Lastly, one convenient part of having other auth-related functionallity in this hook is the developer doesn't need to remember all the requirements when performing a certain action. For instance, on the logoutUser function, you can see we clear the client store (i.e. nuke the cache). If I were to manually have that logout code in all the components that could possibly log the user out, I may forget to do this which would result in undesired behavior.

In sum, this is a pretty straightforward refactor but figured I'd share these convenient hooks that I have found helpful during development.

Stay up to date

Get notified when I publish something new, and unsubscribe at any time.