11

I'm writing a Next.js project, and implementing authentication using GitHub and next-auth. In the examples of next-auth, there's a call to useSession(), which returns two objects: session and loading. However, none of the examples that I've seen actually use the loading object.

import React from 'react'
import { 
  useSession, 
  signin, 
  signout 
} from 'next-auth/client'

export default () => {
  const [ session, loading ] = useSession()

  return <p>
    {!session && <>
      Not signed in <br/>
      <button onClick={signin}>Sign in</button>
    </>}
    {session && <>
      Signed in as {session.user.email} <br/>
      <button onClick={signout}>Sign out</button>
    </>}
  </p>
}

Question: What is the purpose of loading, and how is it used in practice?

2 Answers2

8

The loading option indicates the session state is being updated; it is true when session data is being fetched and false when it is done checking.

It's slightly complex as the session property can be populated already even if it's loading (e.g. because it already has a cached value it can use from a previous call), so technically session can be populated even when loading is true.

If using the NextAuth.js provider in pages/_app.js the session object returned from useSession can also be populated if getSession() has been called in getInitialProps() or getServerSideProps().

If you have an active session, actions like the window gaining or losing focus will cause NextAuth.js to check the session state again in the background, to try and make sure it's not stale.

tl;dr

When you check loading you probably also want to check session is not null first. If the session state is an object, the user has a valid session and you don't need to wait for loading to return.

However, if session is null and loading is false then they definitely don't have an active session.

Iain Collins
  • 6,774
  • 3
  • 43
  • 43
  • 4
    I was expecting `loading` to be `true` after `signIn()` is being called. I wanted to use it to show a spinner on the login-submit-button while `signIn()` did its thing. **But I had to learn that `signIn()`** (and also `singOut()`) **does not have any effect on `loading`.** Probably I'm having a major misunderstanding. Maybe someone can clear the fog for me .. – Tobi Dec 18 '20 at 06:08
  • @Tobi I think that is a fair assumption! I'm not sure that it does, but it seems entirely reasonable to expect and if it's not happening I think we could change it. Calling either `signIn()` or `signOut()` *should* change the current session state, but - as you say - I'm not sure that it does actually change the `loading` value. – Iain Collins May 10 '21 at 16:11
0

You can create your own loading functionality by creating your own useState:

const [loading, setLoading] = useState(false);;

function handleGoogleLogIn() {
  signIn("google");
  setGoogleLoading(true);
}

and then in your html

{ loading && (<div> your loading spinner or anything...</div>) }
Sakar
  • 11
  • 3