This is the useEffect
code in the React component.
import { useSession } from '@supabase/auth-helpers-react'
const session = useSession()
useEffect(() => {
if (session) {
console.debug('stay in page')
} else {
console.debug('goto login')
router.push('/login').then(
() => {
console.debug('goto login done')
}
)
}
}, [session, router])
It uses a supabase to manage auth (session).
It has a very weid issue when refresh page, (login, logout redirect through router has no issues at all, only when Refresh page.), both branches will be reached, so in js console, we could see logs from both condition branches.
'stay in page'
and goto login
/ goto login done
.
I assume it is due to
session
changed after refresh. 1st time is undefined, to trigger the 2nd brachrouter.push
, immediately, when session be found, triggers the 1st branchstay in page
.
Is there any suggestion to bypass it? Or any good practice to handle page refresh in React/NextJS? Or anyone has similar or the same issue before?
Finally, I got the root cause for this.
It is from the useSession
hook from supabase auth helper, it is an async function, and it does not include the state of whether it is loading or error, which it means it will always be null in the beginning (which it means it is in loading).
The simple solution to solve it, is to use useSessionContext
directly instead. session
will still be gotten in an async way, but isLoading
and error
state can be gotten in a sync way to resolve this issue, and they can be used for condition branching inside useEffect
.
New code will be like this:
import { useSessionContext } from '@supabase/auth-helpers-react'
const {isLoading, session} = useSessionContext()
useEffect(() => {
if (isLoading) {
console.debug('show loading page')
}
else if (session) {
console.debug('stay in page')
}
else {
console.debug('goto login')
router.push('/login').then(
() => {
console.debug('goto login done')
}
)
}
}, [session, isLoading, router])