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.
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>
);
}