Remove back button from header in React Native and React Navigation - javascript

Tried these two ways, but none worked:
options={{
headerLeft: () => {
return null}
}}
// method 2
screenOptions={{
headerLeft: null,
}}

You could do it for all screens or for one of them like so:
<Stack.Navigator
// For all screens inside this Stack Navigator
screenOptions={{
headerBackVisible: false,
}}
>
<Stack.Screen
// For the login screen inside this Stack Navigator
options={{ headerBackVisible: false }}
component={LoginScreen}
name="Login"
/>
</Stack.Navigator>

Related

How can I add an onPress event listener to a drawer navigation item in react native react navigation?

I have a drawer navigation configured in the following way:
const CustomDrawerContent = () => { return ( <DrawerItem label="Log out2" onPress={() => logOut()} /> ) }
const loginStack = () => (
<Stack.Navigator >
<Stack.Screen name='LandingScreen' component={LandingScreen} options={{headerShown: false}} />
<Stack.Screen name='LoginScreen' component={LoginScreen} options={{headerShown: false}} />
<Stack.Screen name='RegisterScreen' component={RegisterScreen} options={{headerShown: false}} />
</Stack.Navigator>
)
return (
<NavigationContainer>
<Drawer.Navigator
screenOptions={{
drawerStyle: { backgroundColor: 'white' },
drawerPosition: 'right'
}}>
{!user ? (
<Drawer.Screen
name="PublicStack"
component={loginStack}
options={{headerShown: false}}
/> )
:
(<>
<Drawer.Screen name='Search cocktails' component={HomeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Profile' component={ProfileScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Publish a recipe' component={PublishRecipeScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Favorites' component={FavoritesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Published recipes' component={PublishedRecipesScreen} options={{ header: () => <Header/> }} />
<Drawer.Screen name='Log out' component={CustomDrawerContent} options={{ header: () => <Header/> }} />
<Drawer.Screen name='CocktailDetailScreen' component={CocktailDetailScreen} options={{
header: () => <Header/>,
drawerLabel: () => null,
title: undefined
}} />
</>
)}
</Drawer.Navigator>
</NavigationContainer>
)
All screens work fine, but I want Log out to execute a logout function onPress. As I understand, I can't add this event listener directly on the screen component, so I followed this doc (https://reactnavigation.org/docs/drawer-navigator/#drawercontent) and tried a few different things:
I created the component CustomDrawerContent which is a DrawerItem.
If I pass CustomDrawerContent as the component to the Log out screen (as the code is right now), when I click on it I get redirected to a blank page that renders CustomDrawerContentcomponent, which isn't what I want.
If I pass CustomDrawerContent as drawerContent props to the drawer navigator, like the doc says (example below), all other screens dont render anymore, which is again not what I want.
<Drawer.Navigator drawerContent={(props) => <CustomDrawerContent />}>
{/* screens */}
</Drawer.Navigator>
If I put the drawer item together with the screens inside the navigator, the app throws the following error:
useNavigationBuilder.tsx:134 Uncaught Error: A navigator can only contain 'Screen', 'Group' or 'React.Fragment' as its direct children (found 'DrawerItem'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
So how can I add the item to the drawer without 'overwritting' the screens?
Or is there other way to put a simple logout button in the drawer?
Full code can be found here: https://github.com/coccagerman/mixr

Nested navigator options not working or even showing up

I want to show a back button in the header of a screen that is nested in 2 navigators.
I will first show you how I am nesting the screen, followed by what I have tried
Main stack navigator:
<Provider store = {store}>
<StatusBar style="light" />
<NavigationContainer>
<Stack.Navigator initialRouteName="Login">
<Stack.Screen name="Login"
component={Login}
options= {{
headerLeft: null,
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20,
color: '#FFFFFF'
},
headerStyle: {
backgroundColor: '#121212'
}
}}/>
<Stack.Screen
name="Tabs"
component={Tabs} <-------------- The screen is nested in tabs
options= {{
title: " ",
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 24,
color: '#FFFFFF'
},
headerStyle: {
backgroundColor: '#121212'
},
}}/>
</Stack.Navigator>
</NavigationContainer>
</Provider>
);
}
}
Tab navigator, nested within the stack navigator as "Tabs":
//Bottom Tabs
function Tabs() {
return (
<Tab.Navigator
initialRouteName="Home"
tabBarOptions={{
activeTintColor:"#FFFFFF",
inactiveTintColor:"#696969",
style: {
backgroundColor: '#000000'
},
}}>
<Tab.Screen
name="Create"
component={createFlowStack} <------------ This stack is where the screen header I want to add a back button to lies
options={{
tabBarLabel: ' ',
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-add-circle" size={size} color={color} />
),
}}
/>
</Tab.Navigator>
);
}
I have deleted the other tabs as they are not relevant to the question. This tab, create, is nesting another stack navigator, createFlowStack:
createFlowStack, which is shown when you click on the bottom tab "create"
<CreateStack.Navigator
initialRouteName="Create"
>
<CreateStack.Screen
name="Create"
component={Create} />
<CreateStack.Screen
name="Screenshot"
component={Screenshot}
// options={({ navigation }) => ({
// headerRight: () => (
// <Button
// onPress={() => navigation.goBack()}
// title="Info"
// color="#fff" />
// ),
// })}
/>
As you can see, the options are commented out, but it wouldn't matter any way. I am trying to show a back button in header left of this screen, but nothing I have tried works.
What I have tried:
headerBackTitle: "back"
headerBackTitle: " "
A custom header left button
headerRight: " "
The custom header right button you see commented out
NOTHING works, nothing shows up, its like one of the navigators that createFlowStack is nested in is overriding everything. Please let me know how to fix this issue!
Updating the expo SDK from 39 to 40 fixed the issue!

React navigation drawer navigator with header back button

I'm using the drawer navigation from React Navigation v5. In my root file i've created the drawer navigator. Some of the screens inside of this navigator has a nested stack navigator. The first item is dashboard and the second item is Relations.
The problem is when I go to relations I don't get a back button for going to the first screen (Dashboard). Is it possible to add this to my relations screen?
Root code:
<NavigationContainer>
<DrawerNavigator.Navigator
drawerContent={(props) => (
<SidebarComponent {...props} user={this.props.device.user} />
)}
drawerPosition="right"
drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}>
{this.props.authenticated && this.props.device.api_key ? (
<>
<DrawerNavigator.Screen
name="Home"
options={{
headerShown: false,
icon: 'tachometer-alt',
category: 'dashboard',
}}
component={DashboardStack}
/>
<DrawerNavigator.Screen
name="Relations"
options={{
icon: 'address-book',
category: 'dashboard',
}}
component={RelationsStack}
/>
</>
) : (
<>
<DrawerNavigator.Screen
name="login"
options={{headerShown: false, gestureEnabled: false}}
component={LoginStack}
/>
</>
)}
</DrawerNavigator.Navigator>
</NavigationContainer>
Relation stack code:
import 'react-native-gesture-handler';
import React from 'react';
import {createStackNavigator} from '#react-navigation/stack';
import RelationsListScreen from '../RelationsListScreen';
import {colors} from '../../../assets/styles/variables';
const Stack = createStackNavigator();
function RelationsStack() {
return (
<Stack.Navigator>
<Stack.Screen
options={{
headerShown: true,
headerTintColor: '#FFF',
headerStyle: {
backgroundColor: colors.primary,
shadowColor: 'transparent',
},
}}
name="Relations"
component={RelationsListScreen}
/>
</Stack.Navigator>
);
}
export default RelationsStack;
You could create a stack navigator that is a screen of your drawer navigator (when the user is authenticated) which has Home and Relations as screens. I've called this navigator AuthenticatedNavigator in the example below:
const AuthenticatedStack = createStackNavigator();
// ...
const AuthenticatedNavigator = () => {
return (
<AuthenticatedStack.Navigator screenOptions={{headerShown: false}}>
<AuthenticatedStack.Screen
name="Home"
options={{
icon: 'tachometer-alt',
category: 'dashboard',
}}
component={DashboardStack}
/>
<AuthenticatedStack.Screen
name="Relations"
options={{
icon: 'address-book',
category: 'dashboard',
}}
component={RelationsStack}
/>
</AuthenticatedStack.Navigator>
);
};
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItem
label="Home"
onPress={() => props.navigation.navigate('Home')}
/>
<DrawerItem
label="Relations"
onPress={() => props.navigation.navigate('Relations')}
/>
</DrawerContentScrollView>
);
}
function App() {
const authenticated = true;
return (
<NavigationContainer>
<DrawerNavigator.Navigator
drawerPosition="right"
drawerStyle={{width: '90%', padding: 0, backgroundColor: 'red'}}
drawerContent={(props) => <CustomDrawerContent {...props} />}>
{authenticated ? (
<DrawerNavigator.Screen
name="authenticated"
component={AuthenticatedNavigator}
/>
) : (
<DrawerNavigator.Screen
name="login"
options={{headerShown: false, gestureEnabled: false}}
component={LoginStack}
/>
)}
</DrawerNavigator.Navigator>
</NavigationContainer>
);
}
I've also used a custom drawer content component so the links in the drawer still work correctly after using the approach of creating another stack navigator. You can read more about providing a custom drawer component in the documentation here: https://reactnavigation.org/docs/drawer-navigator/#providing-a-custom-drawercontent.
I've left out some code and made authenticated a hardcoded value to simplify the example. Also be sure to import DrawerItem, DrawerContentScrollView from #react-navigation/drawer.

Passing Params from Stack-navigator to tab Navigator (react-navigation 5)

I am trying to pass the user ID from the login screen to the home screen which is part of a nested tab navigator.
here is how my app is structured:
const mainStack = () =>(
<Tab.Navigator
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={Homescreen}
options = {{headerStyle: {backgroundColor: 'yellow'}}}
/>
<Tab.Screen name="Profile" component={otherStack} />
</Tab.Navigator>
)
export default () => (
<NavigationContainer >
<Stack.Navigator screenOptions={{
headerShown: false
}}>
<Stack.Screen name='Welcome' component={WelcomeScreen} />
<Stack.Screen name = 'Register' component = {RegisterScreen} />
<Stack.Screen name= 'Login' component={LoginScreen} />
<Stack.Screen name = 'mainStack' component={mainStack} />
</Stack.Navigator>
</NavigationContainer>
)
Whenever I go from the login screen to Home and call this.props.navigation.getParam('id') I get an error saying that it is not a function. After closer inspection I see that this.props.navigation.state is undefined. Probably meaning that my params aren't passed to the Home screen even though I don't have any issues navigating to it.
I tried using NavigationActions but I get an error that I don't see mentioned anywhere else.
I navigate to Home like this:
this.props.navigation.navigate('Home' { id: 'myId' })
I also tried this syntax:
navigation.navigate('Root', {
screen: 'Settings',
params: { user: 'jane' },
});
but I get the same error
It is also worth noting that I used React.component rather than making my screens into functions. I am not sure if that causes any issues because in the tutorial for react-navigation v5 I saw the guy use functions instead of react components.
any help will be very much appreciated!!
Try this:
props.navigation.navigate('mainStack' { params: {id: 'myId'}, screen: 'Home' )
And when accessing instead of using getParam use props.route.params.id

React Navigation v5 How to hide tab from stack screen

I have an app that is composed of a tabbed navigation with 5 screens and one of them is a stack navigation of two screens. On one of the two stack screens I want to hide the bottom tabs. How can I do that ?
I already checked React Navigation V5 Hide Bottom Tabs but when I tried using navigation.setOptions({ tabBarVisible: false }) it changed the options for the stack navigator not the tab one.
Here is my code
// Screen where I want to hide the BottomTabNavigator
function StackSecondScreen({ navigation }) {
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "indianred"
}}
>
<Text>StackSecondScreen</Text>
</View>
);
}
const Stack = createStackNavigator();
function TabFirstScreen({ navigation }) {
return (
<Stack.Navigator initialRouteName="StackFirst">
<Stack.Screen
name="StackFirst"
component={StackFirstScreen}
options={{
headerShown: false
}}
/>
<Stack.Screen name="StackSecond" component={StackSecondScreen} /> // <== Screen where I want to hide the BottomTabNavigator
</Stack.Navigator>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="First">
<Tab.Screen name="TabFirst" component={TabFirstScreen} />
<Tab.Screen name="TabSecond" component={TabSecondScreen} />
<Tab.Screen name="TabThird" component={TabThirdScreen} />
<Tab.Screen name="TabFourth" component={TabFourthScreen} />
<Tab.Screen name="TabFifth" component={TabFifthScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

Categories