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.

2
  • The component renders a Navigate component regardless of any session value. What exactly are you trying to accomplish?
    – Drew Reese
    Apr 4, 2023 at 7: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 4, 2023 at 7:54

2 Answers 2

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>
  );
}
1
  • Yes I also did something similar to it. Thank you for putting your effort in my question.
    – SOHAM
    Apr 4, 2023 at 8: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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.