Reputation: 361
I am having a bit of trouble trying to dynamically show different items at React-Navigation drawer.
I have a drawer that needs to show different items if the user is logged in or not. In this case, if the user is logged in, the buttons for "RegisterScreen" and "LoginScreen" should NOT be shown and the "Log Out" button should be shown. However, if the user is NOT logged in, then both Register and Login screens should be shown and the Log out button should not.
I have successfully shown the buttons using the code below (Except for the Logout button, I did not do it yet). However, once the user logs out, the app redirects them to the login screen. Since I did not declare them in the drawer, I get the following error:
console.error: The action 'NAVIGATE' with payload {"name":"LoginModal"} was not handled by any navigator.
I do understand that the screens were not added, but I have no idea how they can be hidden when the user is logged in.
Code:
//Added DrawerItemList for the Logout button.
const CustomDrawerContent = (props) => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem
label="Logout"
onPress={async () => {
props.navigation.closeDrawer();
await LogOut().then((result) => {
props.navigation.navigate('LoginModal');
});
}}
/>
</DrawerContentScrollView>
);
};
const [drawerCategories, setDrawerCategories] = useState([]);
//Checks if the user is logged in and sets Login and Register screens in the state.
useEffect(() => {
let mounted = true;
if (mounted) {
AsyncStorage.getItem('userId').then((result) => {
console.log(result);
if (result == null) {
setDrawerCategories([
...drawerCategories,
{name: 'LoginModal', component: {LoginScreen}},
{name: 'RegisterModal', component: {RegisterScreen}},
]);
}
});
}
return () => (mounted = false);
}, []);
return (
<NavigationContainer>
<RootDrawer.Navigator
drawerType="front"
initialRouteName="Home"
mode="modal"
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<RootDrawer.Screen name="Home" component={MainStackScreen} />
//Add the Register and Login buttons here
{drawerCategories.map((drawer) => {
<RootDrawer.Screen name={drawer.name} component={drawer.component} />;
})}
</RootDrawer.Navigator>
</NavigationContainer>
);
Can you please help me figuring out how to fix this error? Thank you so much!
Upvotes: 1
Views: 2309
Reputation: 10143
Not sure what your LogOut
function does, but unless it actually re-runs the effect so that your LoginModal
screen is defined, there won't be a screen named LoginModal
to navigate to.
Looking at your code, your effect won't re-run after you logout. Instead of setting the list of screens in the effect, you should arrange your code to something like this:
userId
useEffect
hook should restore try to restore the userId
from AsyncStorage
like you're doing now, but after restoring, it should update your global store to update the userId
there instead of setting the screenslogOut
function should delete the userId
from AsyncStorage
as well as update the global store so that it's null
.userId
is null
, and they'll automatically change on login or logoutThe docs for authentication flow show an example of how this works using a token and stack navigator: https://reactnavigation.org/docs/auth-flow/
You can use similar strategy with an user id and a drawer navigator.
Upvotes: 2