1

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.

SOHAM
  • 395
  • 1
  • 2
  • 8
  • The component renders a `Navigate` component regardless of any `session` value. What exactly are you trying to accomplish? – Drew Reese Apr 04 '23 at 07:49
  • @DrewReese What i am trying to accomplish : If session is null , user has to log in and is redirected to authentication page "/account" from "/" else if there is session, user is logged in and is redirected to home page "/home" from "/" – SOHAM Apr 04 '23 at 07:54

2 Answers2

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>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Yes I also did something similar to it. Thank you for putting your effort in my question. – SOHAM Apr 04 '23 at 08:09
0

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

SOHAM
  • 395
  • 1
  • 2
  • 8