I'm new in react native and I created a bottom tab navigator. I have 3 menus: Home, Tenants, and WorkOrders. How can I change the WorkOrders to display the button name and header as "Work Orders" instead of "WorkOrders"?
const MainTabNavigator = createBottomTabNavigator({
Home,
Tenants,
WorkOrders
}, {
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
return {
headerTitle: routeName
};
}
});
const MainStackNavigator = createStackNavigator({
MainTabNavigator
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
Menu: {
screen: MainStackNavigator
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
Main: { screen: AppDrawerNavigator }
});
const AppContainer = createAppContainer(AppSwitchNavigator);
Thanks
You can do like this:
const MainTabNavigator = createBottomTabNavigator({
...,
WorkOrders: {
screen: WorkOrders,
navigationOptions: {
title: 'Work Orders'
// You can check more options here: https://reactnavigation.org/docs/en/bottom-tab-navigator.html#navigationoptions-for-screens-inside-of-the-navigator
}
}
},{
// BottomTabNavigatorConfig
})
You can do the same with other react-navigation's API
Related
I have implement react native navigation with 4 tabstack. Every tabstack is with multiple pages, When I moved from first page to next page or next stack. It works fine. but when I moved back to first page of the first stack and click on button of the page. it will move to last visited page of the last visited stack. I am not sure why it is happening.
I am putting my navigation code below
const stackNavigatorConfiguration = {
mode: "card",
defaultNavigationOptions: {
headerStyle: { backgroundColor: Colors.HeaderColor, borderBottomWidth: 0 },
headerTintColor: "#0055FF",
headerTitleStyle: {
fontSize: 20,
fontFamily: Constants.FontFamily,
fontWeight: "bold"
},
headerBackTitle: null,
barStyle: { backgroundColor: Colors.HeaderColor}
}
};
/* User Profile ---------------------------------------------------------------------------*/
const profileTabScreens = {};
profileTabScreens[Constants.Screen.MyProfile] = { screen: UserProfileScreen };
profileTabScreens[Constants.Screen.OrderHistory] = { screen: OrderHistoryScreen };
const profileStack = createStackNavigator(
profileTabScreens,
stackNavigatorConfiguration
);
profileStack.navigationOptions = ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => (
<TabBarItem
icon={Icons.User}
tintColor={tintColor}
routeName={navigation.state.routeName}
/>
),
title:"User"
});
/* Cart ------------------------------------------------------------------------ */
const cartsTabScreens = {};
cartsTabScreens[Constants.Screen.OrderPreview] = { screen: OrderPreviewScreen };
cartsTabScreens[Constants.Screen.OrderSchedulePickup] = { screen: OrderSchedulePickupScreen };
cartsTabScreens[Constants.Screen.OrderConfirm] = { screen: OrderConfirmScreen };
cartsTabScreens[Constants.Screen.AddAddress] = { screen: AddAddressScreen };
cartsTabScreens[Constants.Screen.OrderThankyou] = { screen: OrderThankyouScreen };
const cartsStack = createStackNavigator(
cartsTabScreens,
stackNavigatorConfiguration
);
cartsStack.navigationOptions = ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => (
<TabBarItem
icon={Icons.Cart}
tintColor={tintColor}
routeName={navigation.state.routeName}
/>
),
title:"Carts"
});
/*Deal/Service ------------------------------------------------------------------- */
const dealsTabScreens = {};
dealsTabScreens[Constants.Screen.Service] = { screen:ServicesListScreen };
dealsTabScreens[Constants.Screen.ShopListByService] = { screen:ShopListByServiceScreen };
const dealsStack = createStackNavigator( dealsTabScreens, stackNavigatorConfiguration);
dealsStack.navigationOptions = ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => (
<TabBarItem
icon={Icons.ICCollection}
tintColor={tintColor}
routeName={navigation.state.routeName}
/>
),
title: "Services"
});
/* Home Stack------------------------------------------------------------*/
const homeTabScreens = {};
homeTabScreens[Constants.Screen.Home] = { screen: HomeScreen };
homeTabScreens[Constants.Screen.Vendor] = { screen: VendorScreen };
const homeStack = createStackNavigator( homeTabScreens, stackNavigatorConfiguration);
homeStack.navigationOptions = ({ navigation }) => ({
tabBarIcon: ({ tintColor }) => (
<TabBarItem
icon={Icons.ICBadgeHome}
tintColor={tintColor}
routeName={navigation.state.routeName}
/>
),
title: "Home",
});
/*------------------------------------------------------------*/
const tabScreens = {};
tabScreens[Constants.Screen.Home] = { screen: homeStack };
tabScreens[Constants.Screen.Service] = { screen: dealsStack };
tabScreens[Constants.Screen.Carts] = { screen: cartsStack };
tabScreens[Constants.Screen.MyProfile] = { screen: profileStack };
const mainTab = createMaterialBottomTabNavigator(tabScreens, {
initialRouteName: Constants.Screen.Home,
activeColor: Colors.BottomMenuColor,
inactiveColor: Colors.Gray,
barStyle: { backgroundColor: "#fff" }
});
const screens = {};
screens[Constants.Screen.Launch] = { screen: LaunchScreen };
screens[Constants.Screen.Auth] = { screen: AuthScreen };
screens[Constants.Screen.AuthOTP] = { screen: AuthOTPScreen };
screens[Constants.Screen.AuthPassword] = { screen: AuthPasswordScreen };
screens[Constants.Screen.UserRegisterDetail] = { screen: UserRegisterDetailScreen };
//screens[Constants.Screen.OrderHistory] = { screen: OrderHistoryScreen };
//screens[Constants.Screen.MyProfile] = { screen: UserProfileScreen };
screens[Constants.Screen.Home] = { screen: mainTab };
const mainStack = createStackNavigator(screens, {
initialRouteName: Constants.Screen.Launch,
activeColor: Colors.AppColor,
inactiveColor: Colors.Gray,
labelStyle: Styles.TabbarLabel,
headerMode: "none"
});
export default createAppContainer(mainStack);
I currently have an AppContainer which consists of a bottom tab navigator and currently one more navigation set for Profile settings. I am trying to understand how to properly arrange everything, specifically how to nest navigation in one tab Profile so I can access two other pages QrCode and EditAccount each through two buttons. How do I achieve the below output? I believe I have to nest profile navigation somehow.
MY TABS BELOW
Home
Queue
Profile
:in here i have two other pages i can access QRCode and EditAccounts
App.js
const bottomTabNavigator = createBottomTabNavigator(
{
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="home" size={25} color={tintColor} />
)
}
},
Queue: {
screen: Queue,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="comments" size={25} color={tintColor} />
)
}
},
Profile: {
screen: Profile,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="user" size={25} color={tintColor} />
)
}
}
})
const navigationOptions = ({ navigation }) => {
return {
headerTitle: 'hello',
headerStyle: {
height: '45%',
backgroundColor: 'black'
},
headerTintColor: 'white',
headerLeft: (
<TouchableWithoutFeedback
style={{ /* Put your style here */}}
onPress={() => navigation.goBack()} >
<Ionicons name="ios-arrow-dropleft" size={32} color="white" />
</TouchableWithoutFeedback>
)
}
}
const ProfileNavigator = createStackNavigator({
//Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
Profile: { screen: Profile },
EditAccount: { screen: EditAccount, navigationOptions }
});
const AppNavigator = createSwitchNavigator({
tabs: bottomTabNavigator,
profile: ProfileNavigator
})
const AppContainer = createAppContainer(AppNavigator);
After Applying Answer
The solution offers works as needed with the code below:
const navigationOptions = ({ navigation }) => {
return {
headerTitle: 'hello',
headerStyle: {
height: '45%',
backgroundColor: 'black'
},
headerTintColor: 'white',
headerLeft: (
<TouchableWithoutFeedback
style={{ /* Put your style here */}}
onPress={() => navigation.goBack()} >
<Ionicons name="ios-arrow-dropleft" size={32} color="white" />
</TouchableWithoutFeedback>
)
}
}
const ProfileNavigator = createStackNavigator({
Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
});
//ADDED
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};
const AppNavigator = createSwitchNavigator({
tabs: bottomTabNavigator,
profile: ProfileNavigator
})
const AppContainer = createAppContainer(AppNavigator);
The only issue is I am unsure how to port over the header options to the tabs in the in the bottomTabNavigator. I have a custom component in place for the profile page that makes it look like this (black bar with button icon for Profile):
I can then navigate to the EditAccounts by pressing on the user icon. But when I navigate back from EditAccounts back to profile, the page renders with the navigationOptions header like so:
How do I apply this properly so I can lean simply on the navigationOptions header and push a custom name onto it (get rid of my custom component in that case)?
There are 2 cases.
If you want to keep tabs when accessing QR or EditAccount
const BottomTabNavigator = createBottomTabNavigator({
...
Profile: {
screen: ProfileNavigator,
}
})
const ProfileNavigator = createStackNavigator({
Profile: { screen: Profile},
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
});
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};
const AppContainer = createAppContainer(BottomTabNavigator);
If you don't want to keep tabs
const BottomTabNavigator = createBottomTabNavigator({
...
Profile: {
screen: Profile,
}
})
const AppNavigator = createStackNavigator({
Tabs: BottomTabNavigator,
QR: { screen: GenerateQR, navigationOptions },
EditAccount: { screen: EditAccount, navigationOptions }
})
const AppContainer = createAppContainer(AppNavigator);
UPDATED:
Add navigationOptions to ProfileNavigator to remove header
ProfileNavigator.navigationOptions = () => {
const navigationOptions = {
header: null,
headerMode: 'none',
};
return navigationOptions;
};
My createSwitchNavigator has 3 pages: Login (no header). After login, it sends to the main page where I build my bottom, tab, stack, and drawer navigator.
const MainTabNavigator = createBottomTabNavigator({
Home,
Tenants,
WorkOrders: {
screen: WorkOrders,
navigationOptions: {
title: 'Work Orders'
}
}
}, {
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
if (routeName === 'WorkOrders') {
return {
headerTitle: 'Work Orders'
};
}
return {
headerTitle: routeName
};
}
});
const MainStackNavigator = createStackNavigator({
MainTabNavigator
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
iRent: {
screen: MainStackNavigator
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
Main: { screen: AppDrawerNavigator },
TenantDetails: {
screen: TenantDetails,
navigationOptions: () => {
return {
headerTitle: 'Tenant'
};
}
},
});
const AppContainer = createAppContainer(AppSwitchNavigator);
From the tenants, I navigate to the TenantDetails page, but in the TenantDetails the header is not showing. Why?
The switch navigator doesn't have a header. You can use a stack navigator instead.
Sample Code:
const AppStackNavigator = createStackNavigator({
Login: {
screen: Login,
navigationOptions:{
header: null // to override the header, because even if you don't specify the header title, a header will be shown.
}
},
Main: {
screen: AppDrawerNavigator,
navigationOptions:{
header: null
}
},
TenantDetails: {
screen: TenantDetails,
navigationOptions: {
headerTitle: 'Tenant',
headerLeft: null // If you want to override the back button, use this.
}
},
});
const AppContainer = createAppContainer(AppStackNavigator);
I'm using react native navigation and redux in my code.
Below is my navigation structure
const MainTabNavigator = createBottomTabNavigator({
Home,
Tenants,
WorkOrders: {
screen: WorkOrders,
navigationOptions: {
title: 'Work Orders',
headerTitle: 'Work Orders'
}
}
}, {
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
return {
headerTitle: routeName
};
}
});
const MainStackNavigator = createStackNavigator({
MainTabNavigator
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
Menu: {
screen: MainStackNavigator
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
Main: { screen: AppDrawerNavigator }
});
Then, I have an action file where I navigate from the Login to the Main pages.
async
...
console.debug(response.data); // Here the console shows value 10
NavigationService.navigate('Main', { userID: response.data });
In the HomeScreen page I tried to see the parameter value:
const { navigation } = this.props;
const userID = navigation.getParam('userID', '0');
console.debug(userID); // HERE THE VALUE IS 0, BUT SHOULD BE 10
What I am doing wrong? Thanks
You can't pass params with a SwitchNavigator, it's clearly intended in the doc:
By default, it does not handle back actions and it resets routes to
their default state when you switch away.
If you really need to share objects between screens, you should use redux rather than react-navigation.
I have a link from "Test" page to "TestDetails" page. but When i click this.props.navigation.goBack(null) on "TestDetails" page , it takes me to the first page which is "Home" instead of "Test". Here's my index.js. I really dont know how arrived at this though. Pls what am I doing wrong
const HomeScreen = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({navigation}) => ({
})
}
});
const LoginScreen = createStackNavigator({
Home: {
screen: Login,
navigationOptions: ({navigation}) => ({
})
}
});
const SignupScreen = createStackNavigator({
Signup: {
screen: Signup,
navigationOptions: ({navigation}) => ({
})
}
});
const TestsScreen = createStackNavigator({
Tests: {
screen: Tests,
navigationOptions: ({navigation}) => ({
headerTitleStyle: {
fontWeight: '400',
color: '#333',
fontFamily: 'Nunito-Regular',
fontSize: 18
},
headerStyle: {
elevation: 0, //remove shadow on Android
shadowOpacity: 0, //remove shadow on iOS
fontWeight: 400,
},
title: "Consumer tests",
headerLeft:(<Icon.Button name="menu" size={35}
backgroundColor="transparent" color="#2a486c" onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())}>
</Icon.Button>
),
})
}
});
const TestDetailsScreen = createStackNavigator({
TestDetails: {
screen: TestDetails,
navigationOptions: ({navigation}) => ({
})
}
});
const SettingsScreen = createStackNavigator({
Settings: {
screen: Settings,
navigationOptions: ({navigation}) => ({
title: "Settings",
headerLeft:(<Icon.Button name="arrow-back" backgroundColor="transparent" color="black" onPress={() => navigation.dismiss()}>
<Text style={{fontSize: 15}}></Text>
</Icon.Button>
),
})
},
});
const drawernav = createDrawerNavigator({
Home: {
screen: HomeScreen,
},
Login: {
screen: LoginScreen,
},
SignUp: {
screen: SignupScreen,
},
Tests: {
screen: TestsScreen,
},
TestDetails: {
screen: TestDetailsScreen,
},
Settings: {
screen: SettingsScreen,
},
},{
contentComponent: SideMenu,
});
AppRegistry.registerComponent(appName, () => createAppContainer(drawernav));
Pls what am I doing wrong
const LoginScreen = createStackNavigator({
Home: {
screen: Login,
navigationOptions: ({navigation}) => ({
})
}
})
why Home: here?
could you add info from console or you are not receiving error or warnings?
Remember always refer official guides https://facebook.github.io/react-native/docs/navigation
I have confirmed the react-native-navigation definition, like below code snippet.
goBack() and goBack(null) same that the same!
back to your question:
like #Michael post, you'd better check your navigation stack fist
export interface NavigationScreenProp<S, P = NavigationParams> {
state: S;
dispatch: NavigationDispatch;
goBack: (routeKey?: string | null) => boolean;
dismiss: () => boolean;
navigate(options: {
routeName:
| string
| {
routeName: string;
params?: NavigationParams;
action?: NavigationNavigateAction;
key?: string;
};
params?: NavigationParams;
action?: NavigationAction;
key?: string;
}): boolean;