I have created a navigator with 4 tab navigator screens->Home, Search, Upload and Library; and I have stack navigation screens like Sign up, log in, home tabs, and video.
Now, I want to remove the bottom tab bar from the Upload screen but am not sure whether it is possible?
Below is the exact code that I have written:
import React from 'react';
import 'react-native-gesture-handler';
import {StatusBar} from 'react-native';
import {NavigationContainer, DarkTheme} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import {createMaterialBottomTabNavigator} from '#react-navigation/material-bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialIcons';
import Home from '../screens/Home';
import Search from '../screens/Search';
import Library from '../screens/Library';
import ProfileAuthor from '../screens/ProffileAuthor';
import Shoot from '../screens/Shoot';
import LoginScreen from '../screens/LoginScreen';
import SignUp from '../screens/SignUp';
const Stack = createStackNavigator();
const Tab = createMaterialBottomTabNavigator();
function myTabs() {
return (
<Tab.Navigator
initialRouteName="Home"
activeColor="#000"
inactiveColor="#000"
barStyle={{
backgroundColor: '#FFF',
}}>
<Tab.Screen
name="Home"
component={Home}
options={{
title: 'Home',
tabBarLabel: 'Home',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons color={color} name="home" size={26} />
),
}}
/>
<Tab.Screen
name="Search"
component={Search}
options={{
title: 'Search',
tabBarLabel: 'Search',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons color={color} name="search" size={26} />
),
}}
/>
<Tab.Screen
name="Upload"
component={Shoot}
options={{
title: 'Upload',
tabBarLabel: 'Upload',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons color={color} name="add-box" size={26} />
),
}}
/>
<Tab.Screen
name="Library"
component={Library}
options={{
title: 'Library',
tabBarLabel: 'Library',
tabBarIcon: ({color}) => (
<MaterialCommunityIcons
color={color}
name="person-outline"
size={26}
/>
),
}}
/>
</Tab.Navigator>
);
}
const Routes = () => {
return (
<NavigationContainer theme={DarkTheme}>
<Stack.Navigator>
<Stack.Screen
name="login"
component={LoginScreen}
options={{
header: () => null,
}}
/>
<Stack.Screen
name="signup"
component={SignUp}
options={{
header: () => null,
}}
/>
<Stack.Screen
name="Home"
component={myTabs}
options={{
header: () => null,
}}
/>
<Stack.Screen
name="Video"
component={ProfileAuthor}
options={{
header: () => null,
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
export default Routes;
could anyone please tell me whether it is possible in this structure, if yes then how to implement? any help would be great.
tabBarVisible: false
It is working when you used createBottomTabNavigator from #react-navigation/bottom-tabs. but if you will use createMaterialBottomTabNavigator from #react-navigation/material-bottom-tabs to create bottom tabs, it's not working. createMaterialBottomTabNavigator can't hide the tab bar, you can see that there is no such option in docs. You should try to nest the bottom-tabs navigator inside the stack navigator if you want it to disappear on the other screens of the stack navigator. The below code is for the hide tab bar in createBottomTabNavigator.
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const BottomTabs = createBottomTabNavigator();
<BottomTabs.Navigator>
<BottomTabs.Screen name={AppRoute.MORE} component={MoreStack}
options={({ route }) => ({
tabBarVisible: getTabBarVisibility(route),
tabBarLabel: languages.stack_More
})}
/>
</BottomTabs.Navigator>
const getTabBarVisibility = (route: any) => {
const routeName = route.state ? route.state.routes[route.state.index].name: '';
if (routeName === AppRoute.PROFILE
|| routeName === AppRoute.HELP_CENTER
|| routeName === AppRoute.TERMS_CONDITION) {
return false;
}
return true;
}
Related
I have my navigators arranged like this.
Bottom Navigator
2. Stack Navigator
3. Material Top Tabs Navigator
4. Home Screen
I have created headerRight button in StackNavigator's ScreenComponent like this.
export default HomeDashboardNavigation = ({route, navigation}) => {
return (
<DashboardStack.Navigator>
<DashboardStack.Screen name="TopTabNavigator" component={TopTabNavigator}
options={{
headerShown: true,
headerShadowVisible: false,
headerStyle:{backgroundColor:'#FEF8F0'},
headerTitle: (props) => <LogoTitle {...props} />,
headerTitleAlign: 'center',
headerRight: () => (
<TouchableOpacity onPress={() => {
// Need to pass a boolean value to HomeScreen
}}
>
<HintComponent />
</TouchableOpacity>
),
}}
/>
</DashboardStack.Navigator>
)
}
My TopTabNavigator looks like this:
const TopTabNavigator = ({route, navigation}) => {
return (
<Tab.Navigator tabBar={props => <TabBar {...props} />} >
<Tab.Screen name="HomeScreen" component={HomeScreen} />
<Tab.Screen name="Second" component={SecondScreen} />
<Tab.Screen name="Third" component={ThirdScreen} />
<Tab.Screen name="Fourth" component={FourthScreen} />
</Tab.Navigator>
)
}
My HomeScreen is:
const HomeScreen = (props) => {
const isHeaderRightClicked = false; //Need to get the value here
return (
<ScrollView>
</ScrollView>
);
}
I am using react native navigation 6. I tried using setParams and setting route.params and tried to get is in HomeScreen using useEffect on props.navigation but it never gets executed.
I don't know how to pass value from onPress event to the screen. HomeScreen is embedded in TopTabNavigator which is a Screen component of StackNavigator whose header button click sets the value.
Could you please suggest a good way to do this.
Try something like my example below. Here a useState boolean hook [isClicked, setIsClicked] is defined, where the onPress-function changes this boolean on every press. The state isClicked in then passed through the TopTabNavigator to the HomeScreen where it can be used.
HomeDashboardNavigation file:
export default HomeDashboardNavigation = ({ route, navigation }) => {
const [isClicked, setIsClicked] = useState(false);
return (
<DashboardStack.Navigator>
<DashboardStack.Screen
name="TopTabNavigator"
options={{
headerShown: true,
headerShadowVisible: false,
headerStyle: { backgroundColor: "#FEF8F0" },
headerTitle: (props) => <LogoTitle {...props} />,
headerTitleAlign: "center",
headerRight: () => (
<TouchableOpacity
onPress={() => {
setIsClicked((state) => !state);
}}
>
<HintComponent />
</TouchableOpacity>
),
}}
>
{(props) => <TopTabNavigator isClicked={isClicked} {...props} />}
</DashboardStack.Screen>
</DashboardStack.Navigator>
);
};
TopTabNavigator file
const TopTabNavigator = ({ isClicked, route, navigation }) => {
return (
<Tab.Navigator tabBar={(props) => <TabBar {...props} />}>
<Tab.Screen name="HomeScreen">
{(props) => <HomeScreen isClicked={isClicked} {...props} />}
</Tab.Screen>
<Tab.Screen name="Second" component={SecondScreen} />
<Tab.Screen name="Third" component={ThirdScreen} />
<Tab.Screen name="Fourth" component={FourthScreen} />
</Tab.Navigator>
);
};
HomeScreen file
export const HomeScreen = (props) => {
const isHeaderRightClicked = props.isClicked;
return <ScrollView></ScrollView>;
};
I want to add icons on my bottom navigator but I don't know how or where to put it. Can someone help me? I'm currently learning react native so please bear with me. Thank you!.
screenshot of bottom navigator
Here is my code for navigation:
import { StyleSheet } from "react-native";
import { createAppContainer, createSwitchNavigator } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { createBottomTabNavigator } from "react-navigation-tabs";
import SignInScreen from "./src/screens/SignInScreen";
import SignUpScreen from "./src/screens/SignUpScreen";
import RestaurantScreen from "./src/screens/RestaurantScreen";
import RestaurantDetailScreen from "./src/screens/RestaurantDetailScreen";
import MapScreen from "./src/screens/MapScreen";
import MyDealsScreen from "./src/screens/MyDealsScreen";
import { setNavigator } from "./src/navigationRef";
import Header from "./src/components/Header";
import React from "react";
const switchNavigator = createSwitchNavigator({
loginFlow: createStackNavigator({
Signin: SignInScreen,
Signup: SignUpScreen,
}),
mainFlow: createBottomTabNavigator({
List: createStackNavigator({
RestaurantList: RestaurantScreen,
RestaurantDetail: RestaurantDetailScreen,
}),
Map: MapScreen,
MyDeals: MyDealsScreen,
}),
});
you can do this please check official document for reference
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator
initialRouteName="Feed"
screenOptions={{
tabBarActiveTintColor: '#e91e63',
}}
>
<Tab.Screen
name="Feed"
component={Feed}
options={{
tabBarLabel: 'Home',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Notifications"
component={Notifications}
options={{
tabBarLabel: 'Updates',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="bell" color={color} size={size} />
),
tabBarBadge: 3,
}}
/>
<Tab.Screen
name="Profile"
component={Profile}
options={{
tabBarLabel: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
);
}
I have a navigation container that calls a function to my stack. I would like to navigate to a tab screen from a stack screen AND change a state in that tab screen. I have given some code below and a demo. In the demo you can see on screen3(stack screen) I am trying to navigate to Home(tab screen) and change a state so that it renders the MapHome screen.
I am unsure how to pass the state to the bottom tab screen without rendering it elsewhere.
I appreciate any insight more than you know.
here is my demo as well as some code below of App.js. You must run the demo in IOS or android, it will not work for web.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import Home from './Home'
import ListHome from './screens/screen1'
import MapHome from './screens/screen2'
import Screen3 from './screens/screen3'
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Stack.Navigator
initialRouteName="Home">
<Stack.Screen name="Home" component= {Home} options={{headerShown: false}}/>
<Stack.Screen name="Screen1" component= {ListHome} options={{headerShown: false}}/>
<Stack.Screen name="Screen2" component= {MapHome} options={{headerShown: false}}/>
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator
initialRouteName="Home"
screenOptions={{
tabBarActiveTintColor: '#F60081',
tabBarInactiveTintColor: '#4d4d4d',
tabBarStyle: {
backgroundColor: '#d1cfcf',
borderTopColor: 'transparent',
},
}}
>
<Tab.Screen
name="Home"
component={MyTabs}
options={{
tabBarLabel: 'Home',
headerShown: false,
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen
name="Screen3"
component={Screen3}
options={{
tabBarLabel: 'Screen3',
headerShown: false,
tabBarIcon: ({ color, size }) => (
<MaterialCommunityIcons name="account-group" color={color} size={size} />
),
}}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
const Stack = createStackNavigator();
You can pass a parameter from Screen3 to the Home screen.
I have forked your demo and did some small refactoring (including changing from Class to Function components just for preference) so you may need to adapt it to your needs. You can find it here.
In Screen3 you can modify your onPress logic to the following:
navigation.navigate('Home', {
screen: 'Home',
params: {
componentToShow: 'Screen2'
}
});
Here's a breakdown of why you are seeing Home twice:
navigation.navigate('Home', { // <-- Tab.Screen name.
screen: 'Home', // <-- Stack.Screen name.
params: {
componentToShow: 'Screen2'
}
});
With this code you are now passing a route.param to the Home screen. I've included a useEffect to run any time route.params changes.
const [whichComponentToShow, setComponentToShow] = React.useState("Screen1");
React.useEffect(() => {
if(route.params && route.params.componentToShow) {
setComponentToShow(route.params.componentToShow);
}
}, [route.params]);
Now, whenever a User navigates to the Home screen and a componentToShow route parameter is provided, the Home screen will update.
I'm making an app in which I have more than one type of navigation, but I'm not sure how to implement it until now, my apps only had one type of navigation. I tried to read the react-navigation docs that talked about this particular implementation, but I couldn't do it. Can someone help me?
So you guys understand, I'm trying to implement a Stack navigator inside a Tab navigator so that when the user clicks on a point in a map, a details page shows up to him.
Here's what I tried to do
import React from 'react'
import { NavigationContainer } from '#react-navigation/native'
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
import { createStackNavigator } from '#react-navigation/stack'
import { Map } from '../pages/Map'
import { Detail } from '../pages/Detail'
import FiIcon from '#expo/vector-icons/Feather'
const Tab = createBottomTabNavigator()
const Stack = createStackNavigator()
export const UsersRoutes = () => {
return (
<>
<NavigationContainer>
<Tab.Navigator
initialRouteName='Mapa'
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Mapa') {
iconName = 'map'
} else if (route.name === 'Pesquisar') {
iconName = 'search'
} else {
iconName = 'user'
}
return <FiIcon name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'black',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name='Mapa' component={Map} />
<Tab.Screen name='Pesquisar' component={() => <Text>Search</Text>} />
<Tab.Screen name='Perfil' component={() => <Text>Profile</Text>} />
</Tab.Navigator>
</NavigationContainer>
<NavigationContainer>
<Stack.Navigator headerMode='none'>
<Stack.Screen name='Mapa' component={Map} />
<Stack.Screen name='Detalhes' component={Detail} />
</Stack.Navigator>
</NavigationContainer>
</>
)
}
What you can do is:
const MapaStack = () => (
<Stack.Navigator>
<Stack.Screen name="Mapa" component={MapaScreen} />
<Stack.Screen name="AnyScreen" componnent="AnyScreen" />
</Stack.Navigator>
);
const Tabs = () => (
<Tab.Navigator>
<Tab.Screen name="Mapa" component={MapaStack} />
<Tab.Screen name="Pesquisar" component={PesquisarScreen} />
</Tab.Navigator>
);
// you could use Tabs directly instead of AppStack but there can be more requirements...
const AppStack = () => (
<Stack.Navigator>
<Stack.Screen name="Tabs" component="Tabs" />
</Stack.Navigator>
);
Basically, you can pass Navigators instead of Screens as component prop. And you need to use AppStack inside NavigationContainer. You need to think carefully before implementing the navigators because hierarchy is important as it states here.
i still trying to understand this react navigation 5.0.
Fyi i'm using expo, and right now no problem when navigate from one page to other,
problem is when i put navigation for the headerRight.
i put in headerRight in Stack.Navigator because i want this button to be accessible from other screen.
So basically the problem is,
i want to put logout button in headerRight,
but when i try to put navigation.navigate it sait undefined is not an object (evaluating '_this.props')
Then i try to call a function (handleClick),
problem is undefined is not an object too.
May i know what's wrong with my code?
Below is my full code :
import * as React from 'react';
import { Button, View, Text, TextInput, Image, StyleSheet } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import LoginScreen from './src/pages/auth/Login';
import HomeScreen from './src/pages/auth/HomeScreen';
const Stack = createStackNavigator();
export default function App() {
// handleClick = () => {
// this.props.navigation.navigate('Login');
// }
return (
<NavigationContainer>
<Stack.Navigator mode="modal" initialRouteName="Login" screenOptions={{
headerStyle: {
backgroundColor: '#f4511e',
},
headerRight: () => (
<Button
// only alert is ok, the other is error.
// onPress={() => alert('Success Logout!')}
onPress={this.handleClick}
// onPress={this.props.navigation.navigate('Home')}
title="Logout"
color="#fff"
/>
),
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}}>
<Stack.Screen name="Login"
name="Login"
component={LoginScreen}
options={{
title: 'Simple Scorecard',
}} />
<Stack.Screen
name="Home"
component={HomeScreen}
options={{
title: 'Home Menu',
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
Thanks before
You should try this.
You receive the reference to the router (navigation) by converting the property screenOptions to a function.
screenOptions={({route, navigation}) => ({ // get reference to navigation
headerRight: () => (
<Button
onPress={() => navigation.navigate('Home'); // call .navigate on navigation
/>
)
})}
My answer for that.
you have to pass "navigation", and convert "options" to the function
<Stack.Screen
// some code ...
options={({ navigation }) => ({
headerRight: () => (
<TouchableOpacity onPress={() => navigation.navigate("pageYouWantNavigateTo")} >
// some component ...
</TouchableOpacity>
),
})}
/>