Reputation: 11659
I have a function that retrieves a token from SecureStore in react-native
export const isUserLoggedIn = async () =>{
return await SecureStore.getItemAsync('jwtToken') ? true : false
}
This is my navigator:
function RootNavigator() {
const [isLoggedIn, setIsLoggedIn] = useState(false)
console.log("isUserLoggedIn()", isUserLoggedIn());
(async () => {
const someBoolean = await isUserLoggedIn()
console.log("inside then")
setIsLoggedIn(someBoolean)
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
{isLoggedIn || <Stack.Screen name="Root" component={WelcomeScreen} />}
{isLoggedIn && <Stack.Screen name="InvestorProfileQuiz" component={InvestorProfileQuizScreen} />}
{isLoggedIn || <Stack.Screen name="AppTour" component={AppTourScreen} />}
{isLoggedIn || <Stack.Screen name="Login" component={LoginScreen} />}
{isLoggedIn || <Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />}
</Stack.Navigator>
);
})()
console.log("LOGGED IN STATE:", isLoggedIn)
The issue is that the LOGGED_IN_STATE
is logged before the inside then
console.log which means the code isn't blocking and waiting for the isUserLoggedIn()
to resolve. isUserLoggedIn()
returns a promise because it's an async await function, but do I wait for it to resolve before rendering the Stack Navigator? I in short want a logged in user to have access to certain screens and not others. What am I doing wrong?
Upvotes: 2
Views: 1274
Reputation: 2474
I usually handle logged in state with something like this:
function RootNavigator() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
// Passing an empty array as second argument
// makes useEffect behave like componentDidMount
useEffect(() => {
// Wrap logic in the async init function
// since the useEffect callback can't be async
async function init() {
const someBoolean = await isUserLoggedIn();
setIsLoggedIn(someBoolean);
}
init();
}, []);
// Return null or your logged out screen component here.
if (!isLoggedIn) {
return null;
}
return (
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen name="Root" component={WelcomeScreen} />}
<Stack.Screen
name="InvestorProfileQuiz"
component={InvestorProfileQuizScreen}
/>
<Stack.Screen name="AppTour" component={AppTourScreen} />
<Stack.Screen name="Login" component={LoginScreen} />(
<Stack.Screen
name="NotFound"
component={NotFoundScreen}
options={{title: 'Oops!'}}
/>
</Stack.Navigator>
);
}
In your code console.log("LOGGED IN STATE:", isLoggedIn)
does not wait because the async await is incapsulated in the IIFE (https://developer.mozilla.org/en-US/docs/Glossary/IIFE) function scope.
Upvotes: 1