buttons not displaying in expo react navigation header - react-native

I was following this tutorial to learn react navigation in expo. in this header when i give button it is not getting displayed in the header. code below
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Homecomponent}
options={{
headerTitle: ()=> <Icon name="home" />,
headerRight: () => (
<Button
onPress={() => alert("This is a button!")}
title="Info"
color="#00cc00"
/>
)
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
The headerRight button is not getting displayed.
TIA

import { HeaderBackButton } from 'react-navigation-stack';
//import Ionicons from 'react-native-vector-icons/MaterialIcons';// add if you have this
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Homecomponent}
options={{
headerTitle: ()=> <Icon name="home" />,
headerRight: () => (
<HeaderBackButton
onPress={() => alert("This is a button!")}
//title="Info"
color="#00cc00"
/>
// Here you can add your icon to show info sample code for icon is
// <Icon name="info" size={25}/>
)
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
try this code may be helpful for you

Related

navigation.navigate() doesn't work on my nested navigations

Here I'am testing with react navigation v6.
When I press "Go To Log-In" button,
it prints "navigation.navigate is not a function.
Here is my Main Navigation
const DrawerNavigator = () => {
return (
<Drawer.Navigator>
<Drawer.Screen name="User" component={MainStackNavigator} />
<Drawer.Screen name="Notification" component={BottomTabNavigator}
options={ { headerTitle: props => <LogoTitle {...props} /> }}
/>
</Drawer.Navigator>
);
};
here is my one of my nested Navigation
const MainStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen name="Item" component={Items} />
<Stack.Screen name="Profile" component={Profile} />
<Stack.Screen name="LogIn" component={LogIn} />
<Stack.Screen name="Detail" component={Detail} />
</Stack.Navigator>
);
};
const ContactStackNavigator = () => {
return (
<Stack.Navigator screenOptions={screenOptionStyle}>
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>
);
};
Here is my Log in Button in a component named "Items"
export default function Items(navigation) {
useEffect(() => {
console.log("ITem navi: ", navigation);
}, [])
return (
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>Items !</Text>
<Button title="Go to Log-In" onPress={() => navigation.navigate('LogIn')} />
<AccountList />
</View>
);
}
I'am stuck in this error for hours.
Please help me to solve it.
You are accessing it the wrong way
this line
export default function Items(navigation) {
Should be
export default function Items({navigation}) {
Basically you will get all the props as a single parameter which you can destruct and access the navigation prop
In your code complier don't know what is navigation so you need wrap that in porps params like below
export default function Items({navigation}) {

How to keep track of screen title when bottom navigation is used in react native?

I am making use of bottom navigation in React Native and I have a header which is supposed to show on which screen I am at the moment. I am not sure how to change that text on Tab Bar press. I tried making use of onPress event but seems like it does not work.
Here is my code:
<View style={styles.container}>
<StatusBar barStyle="light-content" />
<View style={styles.header}>
<Text style={styles.headerText}>{headerText}</Text>
<SettingsIcon />
</View>
<View style={styles.main}>
<NavigationContainer >
<Tab.Navigator initialRouteName="Home" tabBarOptions={{
activeTintColor: '#FF9F0A',
inactiveTintColor:'white',
style: {
backgroundColor: '#000000',//color you want to change
}
}}>
<Tab.Screen name="Home" component={Home} options={{
tabBarLabel: 'HOME',
tabBarIcon: ({ color, size }) => (
<HomeTabIcon name="home" color={color} size={size} />
),
}}/>
<Tab.Screen name="Controls" component={Controls} options={{
tabBarLabel: 'CONTROLS',
tabBarIcon: ({ color, size }) => (
<ControlsTabIcon name="controls" color={color} size={size} />
),
}}/>
<Tab.Screen name="Charging" component={Charging} options={{
tabBarLabel: 'CHARGING',
tabBarIcon: ({ color, size }) => (
<ChargingTabIcon name="charging" color={color} size={size} />
),
}}/>
</Tab.Navigator>
</NavigationContainer>
</View>
</View>
you can nest your tab navigator in a screen navigator.
You can change the title of your screen navigator header in function of the name of your active screen.
for more information read this.
import React from 'react';
import { NavigationContainer, getFocusedRouteNameFromRoute } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
const RootStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function getHeaderTitle(route : any) {
// If the focused route is not found, we need to assume it's the initial screen
// This can happen during if there hasn't been any navigation inside the screen
// In our case, it's "Feed" as that's the first screen inside the navigator
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
console.log("name route = ", routeName);
switch (routeName) {
case 'Home':
return 'name header tab1';
case 'tab1':
return 'name header tab1';
case 'tab2':
return 'name header tab2';
}
}
const HomeTabs = () => {
return (
<Tab.Navigator>
<Tab.Screen name="tab1" component={Component1} />
<Tab.Screen name="tab2" component={Component2} />
</Tab.Navigator>
);
};
function Root() {
return (
<NavigationContainer>
<RootStack.Navigator>
<RootStack.Screen
name="Home"
component={HomeTabs}
options={({ route }) => ({
headerTitle: getHeaderTitle(route),
})}
/>
</RootStack.Navigator>
</NavigationContainer>
);
};

React Native: where to place Navigators for other screens?

My Application has a BottomTabNavigator, each Tab is linked to a component, which is a StackNavigator.
With that implementation, I can easily switch between the tab screens and also see a detailed screen.
Here is the code of my Screen component:
export default function Screen ({props, children}) {
return (
<>
<Stack.Navigator
screenOptions={{
cardShadowEnabled: false,
header: (props) => {
return <Header {...props} />
},
}}
>
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
<SafeAreaView style={styles.screen}>
<View style={styles.container}>{ children }</View>
</SafeAreaView>
<TabNavigator i18n={i18n}/>
</>
);
}
In the header component, I have an Icon, which onPress needs to navigate to the SettingsScreen.
I am afraid that I am not sure if this is the right implementation of the SettingsNavigator and if yes, how is possible on click on my header menu to navigate to the SettingsScreen.
Here is my Header.js code:
export default function Header (props, navigation) {
...
return (
<View style={styles.container}>
<View style={styles.link} onPress={navigation.navigate("Settings")}>
<MaterialCommunityIcons name="tune" size={32} />
</View>
</View>
)
};
I get an error:
TypeError: navigation.navigate is not a function.(In
'navigation.navigate("Settings")', 'navigation.navigate' is undefined)
How can I access the navigation from my Header component?
I don't think it's a correct implementation.
Please try like following
<Stack.Navigator
initialRouteName={Routes.SignIn}
screenOptions={{
cardShadowEnabled: false,
header: (props) => {
return <Header {...props} />
},
}}
>
<Stack.Screen name={Routes.SignIn} component={SignInScreen} />
<Stack.Screen name={Routes.ForgotPassword} component={ForgotPasswordScreen} />
<Stack.Screen name={Routes.SignUp} component={SignUpScreen} />
</Stack.Navigator>

How can I add navigation in the navigation header?

I'm trying to create a button for navigating to "CreateScreen", the button is placed in the header so I wrote it inside <NavigationContainer> as the documentation suggested, but it seems I don't have access to navigation, I don't actually need it inside NavigationContainer, so if you have other suggestions for implementing(for example, implementing the button inside the component) it will be great.
That's What I'm trying to accomplish(part of app.js)
headerRight: () => {
return <TouchableOpacity>
<Feather name="plus" size={30} onPress={() => navigation.navigate('Create')} />
</TouchableOpacity>
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Index">
<Stack.Screen
name="Index"
component={IndexScreen}
options={{
title: 'Home',
headerRight: () => {
return (
<TouchableOpacity>
<Feather
name="plus"
size={30}
onPress={
() => navigation.navigate('Create')
//Thats what Im trying to accomplish
}
/>
</TouchableOpacity>
);
},
}}
/>
<Stack.Screen name="Show" component={ShowScreen} />
<Stack.Screen name="Create" component={CreateScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
you can use the useNavigation hook to gain access to the navigation prop:
import { useNavigation } from '#react-navigation/native';
const navigation = useNavigation();
navigation.goBack();
source:
https://reactnavigation.org/docs/use-navigation/
In option will return navigation
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Index">
<Stack.Screen
name="Index"
component={IndexScreen}
//navigation<<<<<<<<<<<<<<<<<<<<<<<<<here
options={({navigation, route}) => ({
title: 'Home',
headerRight: () => {
return (
<TouchableOpacity>
<Feather
name="plus"
size={30}
onPress={() => navigation.navigate('Create')}
/>
</TouchableOpacity>
);
},
})}
/>
<Stack.Screen name="Show" component={ShowScreen} />
<Stack.Screen name="Create" component={CreateScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

How to call toggleDrawer in React Navigation 5

I got a React-Navigation 5 drawer menu working using gesture, but I also want to add an icon on the right side of the header to toggle the drawer menu.
I have the navigation setup in my App.js like this:
import {NavigationContainer, DrawerActions} from '#react-navigation/native';
//....... other imports
const HomeStack = createStackNavigator();
const HomeStackScreens = () => (
<HomeStack.Navigator
screenOptions={{
headerStyle: {
backgroundColor: '#5C6BC0',
},
headerTintColor: '#fff',
headerRight: () => {
return (
<TouchableOpacity
onPress={() => DrawerActions.toggleDrawer()}>
<Icon name="bars" color="#FFF" size={18} />
</TouchableOpacity>
);
},
}}>
<HomeStack.Screen
name="Home"
component={HomeScreen}
options={{
header:({scene, previous, navigation}) => {
return (
<TouchableOpacity onPress={() => navigation.toggleDrawer()}>
<Icon name="bars" color="#FFF" size={18} />
</TouchableOpacity>
);
}
}}
/>
<HomeStack.Screen name="Login" component={Login} />
<HomeStack.Screen name="Register" component={Register} />
</HomeStack.Navigator>
);
const ProfileStack = createStackNavigator();
const ProfileStackScreens = () => (
<ProfileStack.Navigator>
<ProfileStack.Screen name="Profile" component={Profile} />
</ProfileStack.Navigator>
);
const SettingStack = createStackNavigator();
const SettingStackScreens = () => (
<SettingStack.Navigator>
<SettingStack.Screen name="Profile" component={Profile} />
</SettingStack.Navigator>
);
const Drawer = createDrawerNavigator();
const DrawerScreens = () => (
<Drawer.Navigator>
<Drawer.Screen name="Home" component={HomeStackScreens} />
<Drawer.Screen name="Profile" component={ProfileStackScreens} />
<Drawer.Screen name="Settings" component={SetttingStackScreens} />
</Drawer.Navigator>
);
class MyApp extends React.Component {
render() {
return (
<NavigationContainer>
<DrawerScreens />
</NavigationContainer>
);
}
}
export default MyApp;
All my others screen are in the form "export default class ScreenName extends React.Component". They are imported in App.js to setup the navigation. The initial screen is Home. The icon is showing correctly on the right side of the header. Calling "DrawerActions.toggleDrawer()" directly does nothing.
I tried "this.props.navigation.toggleDrawer()", and it throws error because "this.props" is undefined.
How can I invoke toggleDrawer() with such a navigation setup? Any help is really appreciated!
Here is the final solution I come up with that requires minimal changes to my original code. The key is to receive "navigation" in screenOptions or options, then I can call navigation methods in the children of screenOptions/options.
<HomeStack.Navigator
screenOptions={({navigation}) => ({
headerStyle: {
backgroundColor: '#5C6BC0',
},
headerTintColor: '#fff',
headerRight: () => {
return (
<TouchableOpacity
style={{paddingRight: 8}}
onPress={() => navigation.toggleDrawer()}>
<Icon name="bars" color="#FFF" size={18} />
</TouchableOpacity>
);
},
})}>