skip to Main Content

I want to somehow get my return value after getting session.

App.jsx file

import { useEffect, useState } from 'react'
import './App.css'
import {Navigate} from 'react-router-dom'
import { supabase } from './helpers/supabaseClient'

function App() {
  const [session, setSession] = useState(null)

  useEffect(() => {
    supabase.auth.getSession().then(({ data: { session } }) => {
      setSession(session)
    })

    supabase.auth.onAuthStateChange((_event, session) => {
      setSession(session)
    })
    
    console.log(session);
  }, [])
  

  return (
    <div className="">
      {session ? <Navigate to="/home"></Navigate> : <Navigate to="/account"></Navigate>}
      {/* {true ? <Navigate to="/home"></Navigate> : <Navigate to="/account"></Navigate>} */}
    </div>
  )
}

export default App

The Navigate function routes to another react component before I am able to retrieve session using useEffect.
I have tried using await function but that too seems to not work. I used setTimeout(2000). But that didn’t work either.

What should be done. I don’t prefer to make it a single page application. I want to use Navigate somehow.

2

Answers


  1. Chosen as BEST ANSWER

    Solved it!

    I just changed

    {session ? <Navigate to="/home"></Navigate> : <Navigate to="/account"></Navigate>}
    

    to

    {session==null?<></>:(session.access_token==null ?<Navigate to="/account"></Navigate> :<Navigate to="/home"></Navigate>  )}
    

    Inside return()

    Edit : you have to use "===" and compare between session === null and session === undefined rather than session.access_token == null and session == null respectively


  2. The component renders a Navigate component regardless of any session value. React component renders are completely synchronous, so a return will always happen prior to any asynchronous logic/side-effects/etc completing.

    I’m guessing you want to wait until the effect runs and populates the session state prior to allowing either of the Navigate components to be rendered. Use a loading state and conditionally return early while the session data is fetched.

    Example:

    function App() {
      const [isLoading, setIsLoading] = useState(true);
      const [session, setSession] = useState(null);
    
      useEffect(() => {
        supabase.auth.getSession()
          .then(({ data: { session } }) => {
            setSession(session);
          })
          .finally(() => {
            setIsLoading(false);
          });
    
        supabase.auth.onAuthStateChange((_event, session) => {
          setSession(session);
        });
      }, []);
      
      if (isLoading) {
        return null; // or loading indicator/spinner/etc
      }
    
      return (
        <div className="">
          <Navigate to={session.access_token ? "/home" : "/account"} replace />
        </div>
      );
    }
    

    If the session state value is either null for unauthorized users, and a defined object for authenticated users, then you can accomplish the same with the single state.

    Example:

    function App() {
      const [session, setSession] = useState(); // <-- initially undefined
    
      useEffect(() => {
        supabase.auth.getSession()
          .then(({ data: { session } }) => {
            setSession(session); // <-- set either null/user object
          });
    
        supabase.auth.onAuthStateChange((_event, session) => {
          setSession(session); // <-- set either null/user object
        });
      }, []);
      
      if (session === undefined) {
        return null; // or loading indicator/spinner/etc
      }
    
      return (
        <div className="">
          <Navigate to={session.access_token ? "/home" : "/account"} replace />
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search