headerLeft issue of TabNavigator - react-native

Why my navigation does not display the icon that I've put on the header left parameter? It seems to me every thing is correct, the Icon is imported. Can you help to find the issue, here is my code:
const TabBarNavig = TabNavigator({
Places : {
screen :AddPlaces,
navigationOptions: ({ navigation }) => ({
title: 'Placements'
})
},
GetPlaces : GetPlaces,
New : New
});
TabBarNavig.navigationOptions = ({ navigation }) => {
const { state: { routes, index } } = navigation;
const navigationOptions = {};
navigationOptions.headerLeft = () => {
return (
<Icon
name = 'menu'
size = { 20}
color = 'white'
style={{paddingTop:20}}
/>
);
}
};

If you're trying to put the icon on top of the tab itself, you will have to use StackNavigator
const TabBarNavig = TabNavigator({
//your component here
})
const YNavigator = StackNavigator ({
Home:{screen: TabBarNavig,
navigationOptions: ({navigation}) => ({
headerLeft: <Icon name="menu" size={20} color="white" />,
})
},
})

if use react navigation version 3 you must use defaultNavigationOptions instead of navigationOptions

const TabBarNavig = TabNavigator({
Places : {
screen :AddPlaces,
navigationOptions: ({ navigation }) => ({
title: 'Placements'
})
},
GetPlaces : GetPlaces,
New : New
});
replace the TabNavigator with createBottomTabNavigator
const TabBarNavig = createBottomTabNavigator({
Places : {
screen :AddPlaces,
navigationOptions: ({ navigation }) => ({
title: 'Placements'
})
},
GetPlaces : GetPlaces,
New : New
});
I think this will solve your issue

Related

setParams not reflecting change in title of the UI

I have a functional component and I want the navigation title to be updated to a data that I get from a data storage. There are plenty of issues and blogs but I can't even get it to update to a literarl text.
DataScreen.js
import React, {useEffect} from 'react';
import {
Button
} from 'react-native';
const DataScreen: () => React$Node = (props) => {
const { navigation } = props;
// didnt work
const updateTitle = () =>{
console.log('trying to update title')
navigation.setParams({
Title: 'New Title', // tired title as well
});
}
useEffect(() => {
updateTitle();
}, []);
return (
<>
<Button title="New Title" onPress={updateTitle} />
</>
);
};
DataScreen.navigationOptions = {
title: ' New Title',
}
export default DataScreen;
if i do console.log(navigation) after calling updateTitle, I see "New Title". Hence, I think it is being set but not reflected in the UI.
my navigator object:
createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) => ({
title: 'Home',
}),
},
Data: {
screen: DataScreen,
navigationOptions: ({navigation}) => ({
title: 'Data'
}),
},
},
{
initialRouteName: 'Home',
headerMode: 'screen',
mode: 'card'
},
);
There are 2 ways to do this
Update your createStackNavigator to reference the title from route.params.title (or Title, if you used capital T)
createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title, // or Title if you use capital T
}),
},
Data: {
screen: DataScreen,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
}),
},
},
{
initialRouteName: 'Home',
headerMode: 'screen',
mode: 'card'
},
);
or
Change setParams to setOptions (without changing anything in createStackNavigator)
const DataScreen: () => React$Node = (props) => {
const { navigation } = props;
// didnt work
const updateTitle = () =>{
console.log('trying to update title')
// navigation.setParams({
// Title: 'New Title', // tired title as well
// });
navigation.setOptions({
Title: 'New Title', // tired title as well
});
}
useEffect(() => {
updateTitle();
}, []);
return (
<>
<Button title="New Title" onPress={updateTitle} />
</>
);
};

How to pass a null screen in Tab Navigation in React Navigation 5

In previous versions of react navigation, we could do this
const CustomTabNavigator = createBottomTabNavigator({
FirstTab: {
screen: FirstScreen,
},
AddButton: {
screen: () => null,
navigationOptions: () => ({
tabBarIcon: (<AddButton/>),
tabBarOnPress: () => {}
})
},
SecondTab: {
screen: SecondScreen,
}
}
Trying to replicate this with react-navigation is causing errors as it won't accept null. Anyone know a way around this?
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs'
const BottomTabNavigator = createBottomTabNavigator()
<BottomTabNavigator.Navigator>
<BottomTabNavigator.Screen
name="FirstTab"
component={FirstScreen}
/>
<BottomTabNavigator.Screen
name="Add"
component={null}
options: () => ({
tabBarIcon: (<AddButton/>),
tabBarOnPress: () => {}
})
/>
<BottomTabNavigator.Screen
name="Second Tab"
component={SecondScreen}
/>
</BottomTabNavigator.Navigator>
Try this, I originally tried to pass it in as an inline function but I got a warning as well. This solved my problem.
Example:
const AddButton = () => {
return null
}
<Tab.Screen name="AddButton" component={AddButton}/>

How to disable the drawer from react navigation for a certain screen

I've seen a lot of stack overflow articles that suggest on how to do this however I tried all of them and none of them seem to work for my case.
my target:
to be able to disable the drawer from all of my screens except my JobFeedScreen.
What I already did:
drawerLockMode: 'locked-closed, drawerLockMode: 'locked-open'
I also tried to put it on the screen itself using
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
const {} = state;
return {
header: null,
drawerLockMode: 'locked-closed' ( or drawerLockMode: 'locked-open')
};
}
here are my codes
for my drawer
AppNavigation.js
//DRAWER NAVIGATOR
const DrawerNav = createDrawerNavigator({
JobFeed: {
screen: JobFeedScreenStack,
navigationOptions: ({navigation})=>({
drawerLabel: 'Job Feed',
drawerIcon: ({ tintColor }) => (
<SimpleLineIcons name="briefcase" size={ Metrics.icons.tiny } color={Colors.heavyGray} />
)
})
},
NotificationScreen: {
screen: NotificationScreenStack,
navigationOptions: {
drawerLabel: 'Notifications',
drawerIcon: ({ tintColor }) => (
<Entypo name = "notification" size = {15} color = {Colors.heavyGray} tintColor={Colors.white}/> )
}
},
ApplicationsFeed: {
screen: ApplicationScreenStack,
navigationOptions: {
drawerLabel: 'Applications',
drawerIcon: ({ tintColor }) => (
<Foundation name = "clipboard-notes" size = {15} color = {Colors.heavyGray} tintColor={Colors.white}/> )
}
},
},
{
initialRouteName: 'JobFeed',
drawerPosition: 'left',
contentComponent: CustomDrawerComponent,
drawerType: 'slide',
drawerLockMode: 'locked-closed',
});
other codes in AppNavigation.js:
// Manifest of possible screens
const AuthStackNavigation = createStackNavigator({
LaunchScreen: {
screen: LaunchScreen,
},
JobFeedScreen: {
screen: JobFeedScreen,
},
FilterScreen: {
screen: FilterScreen,
},
NotificationScreen: {
screen: NotificationScreen,
},
ApplicationScreen: {
screen: ApplicationScreen,
}
},
{
// Default config for all screens
initialRouteName: 'JobFeedScreen',
})
//JOB FEED SCREEN
const JobFeedScreenStack = createStackNavigator({
JobFeedScreen: {
screen: JobFeedScreen,
},
})
//LAUNCH SCREEN
const LaunchScreenStack = createStackNavigator({
LaunchScreen: LaunchScreen,
})
//NOTIFICATION SCREEN
const NotificationScreenStack = createStackNavigator({
NotificationScreen: NotificationScreen,
})
//APPLICATION SCREEN
const ApplicationScreenStack = createStackNavigator({
ApplicationScreen: ApplicationScreen,
})
//FILTER SCREEN
const FilterScreenStack = createStackNavigator({
FilterScreen: FilterScreen
})
// MAIN NAVIGATION
const MainNavigation = createSwitchNavigator({
DrawerNav: DrawerNav,
AuthStackNavigation: AuthStackNavigation,
})
export default createAppContainer(MainNavigation)

How can I change the header navigation title dynamically when switcing tabs

I have 2 tabs and I put inside in createStackNavigator
I am using
"react-navigation": "^2.0.1",
"react-native": "0.55.3",
const Cstack = createStackNavigator({
cstack: {
screen: Screen1,
}
},{
headerMode:'none'
});
const Dstack = createStackNavigator({
dstack: {
screen: Screen2,
},
},{
headerMode:'none'
});
const mytabnavigator= createTabNavigator({
Tab1: {
screen: Cstack,
navigationOptions: ({navigation}) => ({
headerTintColor: 'white',
tabBarIcon: ({focused, tintColor}) => {
return (
<IconIonicons
name='ios-cash'
type='ionicon'
color="#FFFFFF"
size={26}
/>
);
},
})
},
Tab2: {
screen: Dstack,
navigationOptions: ({navigation}) => ({
headerTintColor: 'white',
tabBarIcon: ({focused, tintColor}) => {
return (
<IconIonicons
name='ios-card'
type='ionicon'
color="#FFFFFF"
size={26}
/>
);
},
})
}
}, {
tabBarOptions: {
showIcon: true,
style: {
backgroundColor: '#3f51b5',
},
inactiveTintColor: '#FFFFFF',
activeTintColor: "#FFFFFF"
},
});
const StackTab = createStackNavigator({
stacktab: mytabnavigator,
navigationOptions: ({navigation}) => ({
title: 'Welcome'
})
});
My problem is that they both share the same title Welcome
how can I dynamically change the title when I switch to other tab example I will switch tabsettings then my title would be Settings.
If you are using react navigation <2 i.e ~1.5.* You can set it like this.
const Tabs = TabNavigator({
Tab1:{
screen: Tab1,
navigationOptions: ({navigation}) => {
return { title: "Tab 1 Heading", tabBarLabel:"Tab 1 "}
},
}
Tab2:{
screen: Tab2
navigationOptions: ({navigation}) => {
return { title: "Tab 2 Heading", tabBarLabel:"Tab 2 "}
}
}
})
const Stack = StackNavigator({
tabs: {
screen: Tabs
navigationOptions: ({navigation}) => {
return { title: "Stack"}
}
},
otherScreen: Page
})
I'm not sure why did they remove this feature, when you try the same it won't work on the latest react-navigation. Now title object key is used for fallback it seems.
This may be helpful some users. If you wish you can try downgrading also.
I have the Upgraded the React Navigation to latest today for my project I think this way will be useful to someone
const Tabs = TabNavigator({
Tab1:{
screen: Tab1,
navigationOptions: ({navigation}) => {
return { tabBarLabel:"Tab 1 "}
}},
Tab2:{
screen: Tab2
navigationOptions: ({navigation}) => {
return { tabBarLabel:"Tab 2 "}
}}
});
Tabs.navigationOptions = ({navigation})=>{
const { routeName } = navigation.state.routes[navigation.state.index]; //This gives current route
switch(routeName){
case "Tab1":
headerTitle="Tab 1";
break;
case "Tab1":
headerTitle="Tab 1";
break;
}
return {
headerTitle: headerTitle
}
}
I had the same problem and I couldn't find anything but think I may have figured out a solution.
I added a navigationOptions callback for the screen -
const RootStack = createStackNavigator({
HomeScreen: {
screen: CustomHome,
navigationOptions: ({navigation}) => {
if(navigation && navigation.state && navigation.state.params && navigation.state.params.title) {
return {title: navigation.state.params.title}
}
}
},
InputScreen: {
screen: CustomInput,
navigationOptions: ({navigation}) => {
return {title: navigation.state.params.title}
}
}
})
and in my components in the constructor, I am calling this to update the header name
props.navigation.setParams({title: props.navigation.state.params.input.name})
Hope this helps.
You can set the header title manually in every single screen by making use of navigationOptions. Example:
class TabSettingsScreen extends React.Component {
static navigationOptions = ({navigation}) => ({
title: 'Settings'
})
render() {
return (... );
}
}
remove headerModer: 'none' in child navigators and give required title for screens
const Tstack = createStackNavigator({
tabsettings: {
screen: tabsettings,
navigationOptions: {title : 'Settings'}
},
});
Remove title in mainStackNavigator
const StackTab = createStackNavigator(
{
stacktab: mytabnavigator
},
{
navigationOptions: {
header: null
}
}
);
use TabNavigator
import TabNavigator from 'react-navigation';
declare title for each pages separately
class Screen1 extends React.Component {
static navigationOptions = ({navigation}) => ({
title: 'Settings'
})
}
remove headerMode:'none'

how to use tabBarOnPress in tabnavigator react native

i am stuck in big problem that is i wants onPress event when i clicked on tab.
my code is here:-
static navigationOptions = ({navigation, screenProps}) => {
const params = navigation.state.params || {};
console.log("Params:-",params);
return {
title:Strings.title_dashboard,
headerStyle:{ backgroundColor: Colors.header_blue},
headerTitleStyle:HeaderStyle.titleCenter,
tabBarOnPress: (tab, jumpToIndex) => {
console.log("Tab Click",tab);
jumpToIndex(tab.index);
navigation.state.params.onFocus()
},
headerRight:<TouchableOpacity onPress={()=>Alert.alert(Strings.avanza,Strings.under_imple)}><View><Image source={{uri: "filter_icon"}} style={{height: 18, width: 18,marginRight:10,}} /></View></TouchableOpacity>,
}
}
at here i set the Params like this in componentDidMount:
this.props.navigation.setParams({
handleGrid: this.callServer.bind(this)
})
getting an error here not able to get this click event.
Help me please.
Thank you.
This is my approach. It works for the version 5.x.x of react-navigation:
const BottomTab = createBottomTabNavigator();
const Tabs = props => (
<BottomTab.Navigator
initialRouteName="Foo"
...
<BottomTab.Screen
name="Foo"
component={Foo}
initialParams={props.route.params}
listeners={{
tabPress: e => {
// e.preventDefault(); // Use this to navigate somewhere else
console.log("Foo tab bar button pressed")
},
}}
/>
</BottomTab.Navigator>
);
Read more about listeners.
For version 3.x.x and I hope for the 4th as well please use this one.
let Tabs = createBottomTabNavigator(
{
FooTab: Foo,
},
{
initialRouteName: "FooTab",
defaultNavigationOptions: ({ navigation }) => ({
tabBarOnPress: ({ navigation, defaultHandler }) => {
console.log('onPress:', navigation.state.routeName);
defaultHandler()
},
}),
}
);
For version 2.x.x please use navigationOptions instead of the defaultNavigationOptions.
This is working for me,
static navigationOptions = ({ navigation }) => {
return {
tabBarOnPress: ({previousScene, scene, jumpToIndex}) => {
const { route, index, focused} = scene;
if(focused){
navigation.state.params.scrollToTop()
}
jumpToIndex(0)
}
}
};
I used stack navigator
const Stack = createStackNavigator({
ScreenA: {
screen:ScreenA ,
navigationOptions: () => ({
header: null
}),
},
ScreenB: {
screen:ScreenB ,
navigationOptions: () => ({
header: null
}),
},
});
//Added tabBarOnPress
https://reactnavigation.org/docs/en/stack-actions.html
the popToTop action takes you back to the first screen in the stack, dismissing all the others. It's functionally identical to StackActions.pop({n: currentIndex}).
import { StackActions } from 'react-navigation';
let Tabs = createBottomTabNavigator(
{
FooTab: Foo,
},
{
initialRouteName: "FooTab",
defaultNavigationOptions: ({ navigation }) => ({
tabBarOnPress: ({ navigation, defaultHandler }) => {
// to navigate to the top of stack whenever tab changes
navigation.dispatch(StackActions.popToTop());
defaultHandler();
]},
}),
}
);