I am trying to render certain nav stacks depending on a isAuthenticated
state. The problem that I am having is that AppNavigator
is only rendered on the first render and not with any other changes and I am not sure why. I have tried a useEffect in the AppNavigator
component to set a secondary local state with the callback being isAuthenticated
but no go. I put everything pertinent below. I appreciate any advice.
I have an AppNavigator
that is being rendered in my app.tsx
file.
return (
<ToggleStorybook>
<ApolloProvider client={client}>
<RootStoreProvider value={rootStore}>
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<ErrorBoundary catchErrors={"always"}>
<AppNavigator
initialState={initialNavigationState}
onStateChange={onNavigationStateChange}
/>
</ErrorBoundary>
</SafeAreaProvider>
</RootStoreProvider>
</ApolloProvider>
</ToggleStorybook>
)
The AppNavigator
is returning
export const AppNavigator = (props: NavigationProps) => {
const { isAuthenticated } = useStores()
const colorScheme = useColorScheme()
useBackButtonHandler(canExit)
return (
<NavigationContainer
ref={navigationRef}
theme={colorScheme === "dark" ? DarkTheme : DefaultTheme}
{...props}
>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
{isAuthenticated ? (
<Stack.Screen name="main" component={MainTabs} />
) : (
<Stack.Screen name="signup" component={SignUpStack} />
)}
</Stack.Navigator>
</NavigationContainer>
)
}
I am using mob-state-x-tree for state management and have a setUser
action that is called onAuthStateChanged
per the firebase Auth docs. I'm using email and password login and sign up. I've logged the auth state changes they are working as expected.
function onAuthStateChanged(user: any) {
if (user) {
if (rootStore) {
rootStore.setUser(user)
console.log("we have passed user to root store")
}
}
The setUser
action sets a state isAuthenticated
in a try
catch
setUser: flow(function* (firebaseUser) {
try {
const idToken = yield firebaseUser.getIdToken()
yield AsyncStorage.setItem(
'@lessns:token',
idToken
);
self.isAuthenticated = true
self.user = {id: firebaseUser.uid}
} catch(err) {
console.log(err, 'this is the first time ')
self.isAuthenticated = false
}
}),
You need to make your AppNavigator
component into an observer
so that it will re-render when observable data it depends on changes.
export const AppNavigator = observer((props: NavigationProps) => {
// ...
})