I have developed a bottomTabNavigator in react-native and I have 3 main routes which I want to show in my bottomtabnavigator which are 1) Home, 2) Profile, 3) Chat, So I wrote the following code:
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const Navigation = () => {
return (
<>
<Tab.Navigator>
{user.authLoadingState ? (
<Tab.Screen name="Home" component={LoadingScreen} />
) : user.isLoggedIn ? (
<>
<Tab.Screen
name="Home"
component={HomeScreen}
/>
<Tab.Screen
name="Profile"
component={ProfileScreen}
/>
<Tab.Screen
name="Chat"
component={ChatScreen}
/>
<Stack.Screen name="Update" component={UpdateScreen} /> // this is the screen I don't want in my bottomTab but I want to navigate to it using useNavigation hook.
</>
) : (
<>
<Stack.Screen name="First" component={FirstScreen} />
<Stack.Screen name="SignIn" component={SignInScreen} />
<Stack.Screen name="SignUp" component={RegisterScreen} />
</>
)}
</Tab.Navigator>
</>
);
};
Now, when I go to my Profile screen, I have a button which (should) navigate to another screen which is not mentioned in my Tab Navigator definition, how can I navigate to that screen because obviously I do not want to fill my bottomTabNavigator with different screens, I only want to keep the main screens in my bottomTabNavigator not all. When I was using Stack.Navigator alone, it was fine because I could just keep all my screens under <Stack.Navigator></Stack.Navigator> and navigate to any screen using navigator.navigate(nameOfScreen) with const navigator = useNavigation(). But now, if a screen which is not mentioned inside Tab.Navigator will throw an error if I navigate saying Screen does not exists. Is there any thing I could do to make it work?
to navigate between tab and stack screen you can do this way :
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeScreen}
/>
<Tab.Screen name="Profile Screen" component={StackScreens} />
<Tab.Screen
name="Chat"
component={ChatScreen}
/>
</Tab.Navigator>
</NavigationContainer>
)
function StackScreens() {
return (
<Stack.Navigator screenOptions={{ headerShown: false }} >
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Update" component={UpdateScreen} /> // this is the screen I don't want in my bottomTab but I want to navigate to it using useNavigation hook.
</Stack.Navigator>
);
}
}
I'm not sure if it is exactly that you want, but you can now access from "Profile" to the "UpdateScreen" without showing it in the bottomTabNavigator
Related
Taking this example for the official documentation :
function Root() {
return (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Profile" component={Profile} />
<Stack.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Root"
component={Root}
options={{ headerShown: false }}
/>
<Stack.Screen name="Feed" component={Feed} />
</Stack.Navigator>
</NavigationContainer>
);
}
They just explain here how to navigate to the Profile screen from the Feed screen like this :
navigation.navigate('Root', { screen: 'Profile' });
I would to know how can I navigate to the Feed screen from the Profile screen;
You can just use the navigation object and its navigate function since the Feed screen is nested inside the same navigator as the Root stack.
Destructure the navigation object from the props of Profile.
function Profile({navigation}) {
return ...
}
Now, just use the navigation object as follows in order to navigate to Feed.
navigation.navigate("Feed")
Use case of this problem is to have Drawer menu like "Settings" available only form "Home Screen". And at "Home screen" could be many buttons that link to other screens of Stack Navigation where Drawer is not available.
Main question is how to enable Drawer Navigation only on specific screen of Stack Navigator?
On below example Drawer is available on all pages of Stack. I tried with gestureEnabled but it didn't work:
const StackHome = () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Example1" component={Example1} />
<Stack.Screen name="Example2" component={Example2} />
</Stack.Navigator>
);
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={StackHome} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
On the other hand if I try make Drawer as one of Stack screen, then I have always the same Header bar (example "Header")
Put your drawer navigator inside the home screen:
const DrawerHome = () => (
<Drawer.Navigator screenOptions={{ headerShown: true }}>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
const StackHome = () => (
<Stack.Navigator>
<Stack.Screen
name="DrawerHome"
component={DrawerHome}
options={{ headerShown: false }}
/>
<Stack.Screen name="Example1" component={Example1} />
<Stack.Screen name="Example2" component={Example2} />
</Stack.Navigator>
);
I am using React navigation. I want to add headers to my tab navigator components. How can I do that?
Tab navigation function
const TabNavigation = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Welcome} />
<Tab.Screen name="Favorites" component={Favorites} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
);
};
Stack navigator function
<Stack.Navigator
initialRouteName="SignIn">
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Screen name="TabNavigation" component={TabNavigation}/>
<Stack.Navigator>
You can customize your header dynamically in Stack Navigation screen options prop. For example you can create custom functions like getTitle to determine title dynamically depending on your route.
<Stack.Screen
name="TabNavigation"
component={TabNavigation}
options={({ route }) => ({
//title: getTitle(route),
//headerStyle: styles.headerStyle
//headerTitleStyle: styles.headerTitleStyle
})}
/>
My goal is to have both Top and Bottom navigation bar for Home, Dashboard, and Album, but not for the SignIn. Here's the catch, I wish to put the button on the bottom instead of on the top.
The last remaining puzzle is how to add a Sign In button to the Bottom Navigation Bar.
The roadblock is if you write <Tab.Screen name="Sign In component={SignIn} /> and you press a button with parameter onPress={() => navigation.navigate('SignIn')}, it will navigate you to the Tab.Screen instead of Stack.Screen.
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Home} />
<Tab.Screen name="Dashboard" component={Dashboard} />
<Tab.Screen name="Album" component={Album} />
</Tab.Navigator>
);
}
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen options={{title: ''}} name="MyTabs" component={MyTabs} />
<Stack.Screen name="SignIn" component={SignIn} />
</Stack.Navigator>
);
}
export default function App() {
return (
<Provider store={store}>
<NavigationContainer>
<MyStack />
</NavigationContainer>
</Provider>
);
}
You can use the tabbarbutton like below. This would pass the props and render a the touchableopacity and you can have your own onPress.
You can navigate, here i have given an alert
<Tab.Screen name="Settings"
options={({navigation})=> ({
tabBarButton:props => <TouchableOpacity {...props} onPress={()=>navigation.navigate('SignIn')}/>
})}/>
I have a Navigation Drawer which should appear in all my screen(Except for the Splash screen).
I've got it that way:
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const StackNavigator = () => {
return (
<Stack.Navigator>
<Stack.Screen name="EstateDetails" component={Screens.EstateDetails} />
<Stack.Screen name="Tour" component={Screens.Tour} />
<Stack.Screen name="Comparison" component={Screens.Comparison} />
<Stack.Screen name="Blog" component={Screens.Blog} />
<Stack.Screen name="Auth" component={Screens.Auth} />
</Stack.Navigator>
);
};
const DrawerNavigator = () => {
return (
<Drawer.Navigator drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen name="HomeScreen" component={Screens.Home} />
<Drawer.Screen name="stack" component={StackNavigator} />
<Drawer.Screen name="RegisterEstate" component={Screens.RegisterEstate} />
<Drawer.Screen name="Filter" component={Screens.Filter} />
<Drawer.Screen name="Conditions" component={Screens.Conditions} />
<Drawer.Screen name="Judicial" component={Screens.Judicial} />
<Drawer.Screen name="ContactUs" component={Screens.ContactUs} />
<Drawer.Screen name="ReportBugs" component={Screens.ReportBugs} />
</Drawer.Navigator>
)
};
export const AppNavigator = () => {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Splash">
<Stack.Screen name="Splash" component={Screens.Splash}/>
<Stack.Screen name="Home" component={DrawerNavigator}/>
</Stack.Navigator>
</NavigationContainer>
);
};
In this case, all the okay only stack screens act as drawer screen.
(The screen only loads once and shows the initial load next time, like blog screens).
I need to have the cursor on all pages except splash and to stack some of my pages (like dynamic pages that don't have the same content)
If you want to display same drawer in all other screens just pass {DrawerNavigator} to all other screens where you want to show the Drawer.So in your example if you want to show Drawer in Tour and Blog screen just add
<Stack.Screen name="Blog " component={DrawerNavigator} />
<Stack.Screen name="Tour" component={DrawerNavigator} />
Now you can access in Blog and Tour screen.
If you want to show a different Drawer in other screens then Create a new function.