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

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'

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} />
</>
);
};

I have a problem in my code when updating react-navigation v2 to v3

I want to update the react-navigation library V2 to V3 and change part of my code thinking that there would not be any problems but it turns out that I have problems creating createStackNavigator with a screen of type createDrawerNavigator and that in turn contains createBottomTabNavigator.
my code that works with the previous version was:
export const createRootNavigator = (signedIn = false) => {
const commonNavigationOptions = {
headerStyle: {
shadowColor: 'transparent',
elevation: 0
},
headerTintColor: DEFAULT_THEME.topaz
};
const SignedIn = createStackNavigator(
{
Home: {
screen: Drawer('Home'),
navigationOptions: () => ({
headerStyle: {
height: 0
},
header: getSafeArea(DEFAULT_THEME.backgrouncolorHomeSafeArea)
})
},
Cards: {
screen: Tabs('Cards'),
navigationOptions: () => ({
headerStyle: {
height: 0
}
})
},
);
const SignedOut = createStackNavigator(
{
SignIn: {
screen: LoginContainer,
navigationOptions: () => ({
headerStyle: {
height: 0
},
header: getSafeArea(DEFAULT_THEME.dark)
})
},
SelectableCardsList: { screen: SelectableCardsListComponent },
);
return createSwitchNavigator(
{
SignedIn: { screen: SignedIn },
SignedOut: { screen: SignedOut }
},
{
initialRouteName: signedIn ? 'SignedIn' : 'SignedOut'
}
);
};
const Drawer = (initialRoute) => createDrawerNavigator(
{
Home: { screen: Tabs('Home') },
{
initialRouteName: initialRoute,
contentComponent: CustomDrawerComponent
}
);
const Tabs = (initialRouteName) => createBottomTabNavigator(
{
Home: {
screen: HomeContainer,
navigationOptions: {
tabBarLabel: I18n.t('tabs.me')
}
},
Home2: {
screen: Home2,
navigationOptions: {
tabBarLabel: I18n.t('tabs.credentials')
}
},
{
initialRouteName: initialRouteName,
tabBarComponent: ({ navigation }) => <CustomBottomBarComponent navigation={navigation} navigationState={navigation['state']} />,
tabBarOptions: {
style: {
backgroundColor: 'white'
}
}
}
);
try this solution with react-navigation V3 and send me an error
I try the following:
encapsulate createSwitchNavigator in createAppContainer and separate (SignedOut and SignedOut) createStackNavigator out of createSwitchNavigator, the rest is still the same.
export const createRootNavigator = (signedIn = false) => createAppContainer(createSwitchNavigator(
{
SignedIn: { screen: SignedIn },
SignedOut: { screen: SignedOut }
},
{
initialRouteName: signedIn ? 'SignedIn' : 'SignedOut'
}
));
I get the following error: The component for route 'Home' must be a react component. For Example
import MyScreen from './MyScreen';
...
Home : MyScreen,
}
you can also use a navigator:
The problem is located in this part:
const SignedIn = createStackNavigator(
{
Home: {
screen: Drawer,
Also try to change Drawer for any component (a component with a blank screen) and this works, but I can not insert the Tabs in the Drawer.
Thank you very much for your help.

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)

React-navigation drawer is routing me back to previous screen immediately after rendering item screen

I have a StackNavigation like this:
const AppNavigator = createStackNavigator({
Login: {
screen: Login,
navigationOptions: () => ({
title: 'Login',
headerTintColor: 'white',
headerStyle:{
backgroundColor: '#000',
elevation: 0,
showdowOpacity: 0
},
})
},
Home: {
screen: AppDrawerNavigator,
navigationOptions: () => ({
header: null
})
},
});
With a DrawerNavigator nested inside:
const AppDrawerNavigator = createDrawerNavigator({
Home: {
screen: Home,
navigationOptions: {
drawerLabel: 'Home',
gesturesEnabled: false,
}
},
Favorites: {
screen: Favorites,
navigationOptions: {
drawerLabel: 'Favorites',
}
}
},
{
drawerPosition: 'left',
contentComponent: props => <Drawer {...props} />
});
The initial route of the stack navigator is working fine
Login -> Home
But when I try navigating from Home to Favorites it navigates immediately back to Home after rendering the Favorites screen.
I am using react-navigation#2.11.2 and react-native#0.56.0
With Home being used in both stack and drawer navigator.
There are high chances of name conflicts occurring here.
Try this structure.
const Stack = {
FirstView: {
screen: FirstView
},
SecondView: {
screen: SecondView
},
ThirdView: {
screen: ThirdView
}
};
const DrawerRoutes = {
FirstViewStack: {
name: 'FirstViewStack',
screen: StackNavigator(Stack, { initialRouteName: 'FirstView' })
},
SecondViewStack: {
name: 'SecondViewStack',
screen: StackNavigator(Stack, { initialRouteName: 'SecondView' })
},
ThirdViewStack: {
name: 'ThirdViewStack',
screen: StackNavigator(Stack, { initialRouteName: 'ThirdView' })
},
};
const RootNavigator =
StackNavigator({
Drawer: {
name: 'Drawer',
screen: DrawerNavigator(
DrawerRoutes,
),
},
...Stack
},
{
headerMode: 'none'
}
);
I faced a similar issue when i tried to use a hamburger menu in my Home page (which uses stack navigator to goto other pages).
Check this Git Article also.

My React-Native navigation just wont style

I have an issue that no matter what I try, I just cannot get styling to work on my Stack with Drawer navigator. I've tried several examples and solutions but just none of them work, my navigation stays the default blue.
In my current code below, I've left 2 coloring options open - those two are of the many things I've tried before.
I hope that someone knows what's going on because I'm starting to get clueless.
const MainScreenNavigator = StackNavigator({
'Home': {
screen: Components.HomeScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Home' navigation={navigation} />
})
},
'Scan': {
screen: Components.ScanScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Scan QR' navigation={navigation} />
})
},
'LockInfo': {
screen: Components.LockInfoScreen,
navigationOptions: ({navigation}) => ({
header: <Components.StackHeader title='Lock' navigation={navigation} />
})
},
});
const RootNavigator = DrawerNavigator ({
Home: {
screen: MainScreenNavigator,
},
});
RootNavigator.navigationOptions = {
contentOptions: {
activeBackgroundColor: '#ff5976',
style: {
backgroundColor: '#000000'
}
}
}
const ModalNavigator = StackNavigator(
{
Main: { screen: Main },
Login: { screen: Login },
},
{
headerMode: 'none',
mode: 'modal',
navigationOptions: {
gesturesEnabled: false,
},
https://reactnavigation.org/docs/navigators/stack#Screen-Navigation-Options
checkout this above link, search and add the required styling properties inside your own StackNavigator, headerStyle, headerTitleStyle, headerBackTitleStyle, headerTintColor and so on...
Also for DrawerNavigator, checkout this below link and replicate the code, styling properties for the same are provided.
https://reactnavigation.org/docs/navigators/drawer#DrawerNavigator
Also remove the single inverted commas from Home, Scan and LockInfo