React Navigation between 3 pages - react-native

I am making react native expo app. And i have some problems with react navigations. I have 3 pages:
main.js -> page1.js -> page2.js
I am making navigation between this 3 pages. But when i navigate to each page it making 1 more header. So when i navigate to 3 page i have 2 headers. One header from the page2.js and second from page1.js
I want to have just only one header that is from current page. What i need to do to have this? I need to add one more page where is going to be navigation between this pages? Whatn i need to add? Help me please
Code:
// main.js createStackNavigator:
export default createStackNavigator(
{
Main: {
screen: Main,
navigationOptions: {
header: null,
},
},
Page1: {
screen: Page1,
navigationOptions: ({ navigation }) => ({
headerTitle: "Page1",
}),
},
},
{
initialRouteName: 'Main',
}
);
// Page1.js createStackNavigator:
export default createStackNavigator(
{
Page1: {
screen: Page1,
navigationOptions: {
header: null,
},
},
Page2: {
screen: Page2,
navigationOptions: ({ navigation }) => ({
headerTitle: "Text",
}),
},
},
{
initialRouteName: 'Page1',
}
);
// Page2:
export default createStackNavigator(
{
Page2: {
screen: Page2,
navigationOptions: {
header: null,
},
},
},
{
initialRouteName: 'Page2',
}
);

In your second stack navigator you can add the property headerMode: 'none' under initialRouteName. This will hide the header.

Every StackNavigator you use will render a new Header. In your code you are nesting 3 Stacks. Everytime you navigate to each on of them they will render their Header.
Your parentNavigator will have his first header, leaving it global for the whole time. When you navigate to Page1, this will render his header without hiding his parent header. When you navigate to Page2 same thing, leaving 3 headers from 3 stackNavigators.
If you'll leave the navigation as-is, you have to dinamically hide the header on each on of your stacks.
Taking your first navigator:
{
Main: {
screen: Main,
navigationOptions: {
header: null,
},
},
Page1: {
screen: Page1,
navigationOptions: ({ navigation }) => ({
headerTitle: "Page1",
defaultNavigationOptions:{
header:null //this will hide the header if you are in Page1
}
}),
},
},
{
initialRouteName: 'Main',
}
);
Doing this you will hide the header for Page1, and as Page1 is a stack you will have just the Page1 header.
I don't know how you thinked about navigating between these screens, as this solution would make it harder to navigate from page1 back to the parent Main screen.

Related

Get current page title

I am making react native expo app and i need your help.
I have structure:
main.js => page1.js => page2.js
When i move from main.js to page1.js in createStackNavigator i write title of header of page1.js, but in page1.js i hide the header of page1.js and i have all ok, but when i move to page2.js i have 3 headers!!!!
One of them i hide in page2.js but one other header i do not how to hide, because 1 header is coming from main.js but second from page1.js and i need to hide this header from main.js but if i hide it i will not have header in page1.js.
I want when i navigate to page2.js from page1.js i send data to main.js createStackNavigator. How i can do this??
Code:
// main.js createStackNavigator:
export default createStackNavigator(
{
Main: {
screen: Main,
navigationOptions: {
header: null,
},
},
Page1: {
screen: Page1,
navigationOptions: ({ navigation }) => ({
headerTitle: "Page1",
}),
},
},
{
initialRouteName: 'Main',
}
);
// Page1.js createStackNavigator:
export default createStackNavigator(
{
Main: {
screen: Page1,
navigationOptions: {
header: null,
},
},
Page2: {
screen: Page2,
navigationOptions: ({ navigation }) => ({
headerTitle: "Text",
}),
},
},
{
initialRouteName: 'Main',
}
);
// Page2:
export default createStackNavigator(
{
Main: {
screen: Page2,
navigationOptions: {
header: null,
},
},
},
{
initialRouteName: 'Main',
}
);
You are duplicating rout names, Main is used 3 times,
also page1 and page2 have 2 different routes each,
solution is to create call createStackNavigator in seperate file or in app.js like
export default createStackNavigator(
{
Main: {
screen: Main,
navigationOptions: {
header: null,
},
},
Page1: {
screen: Page1,
navigationOptions: ({ navigation }) => ({
headerTitle: "Page1",
}),
},
Page2: {
screen: Page2,
navigationOptions: ({ navigation }) => ({
headerTitle: "Text",
}),
},
},
{
initialRouteName: 'Main',
}
);
now all the screens will have same header and you can change the title in navigationOptions

Title not working on react-navigation createStackNavigator

I'm using createStackNavigator inside createBottomTabNavigator from react-navigation in my app. I want to have a title on my screen. Following React Navigation's tutorial I've implemented it this way:
createBottomTabNavigator(
{
Home: createStackNavigator(
{screen: HomePage, navigationOptions: () => { title: 'Home'}}),
...
},
However, nothing is displayed in the navigation bar. I've also tried headerTitle though no avail.
What am I doing wrong?
There are 2 ways of setting navigationOptions, object or function
Object
{
screen: HomePage,
navigationOptions: { title: 'Home' }
}
Function that return an object
{
screen: HomePage,
navigationOptions: ({ navigation }) => {
return { title: 'Home' }
}
}
Your code doesn't work is due to you have error in your arrow function, you should add a bracket around the body so that it returning the object.
{ screen: HomePage, navigationOptions: () => ({ title: 'Home'}) }
navigationOptions shouldn't be a function, instead, is a JSON. So, remove the arrows and do it like this:
createBottomTabNavigator(
{
Home: createStackNavigator(
{screen: HomePage, navigationOptions: { title: 'Home'},
...
},

How to stop default transition when using custom tab bar in React Native using React Navigation?

I've made a custom tab bar in a Component which uses StackNavigator like so
export default StackNavigator(
{
Login: {
screen: Login,
},
ForgotPassword: {
screen: ForgotPassword,
},
SignUp: {
screen: SignUp,
},
Home: {
screen: Home,
},
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
},
initialRouteName: 'Home',
},
);
Now my Home screen has a custom made Tab Bar like so
export default () => (
<View>
<Text>HOME</Text>
<TabBar />
</View>
)
I want my Home screens Tab bar to have no transition
Currently it animates (left to right for IOS & bottom to up for Android) when one of the Tab link is clicked
I checked docs & found mode property but it has only 2 props card & modal & I want no animation
How to do it ?
Thanks to #Vojtech, I got the answer
const customAnimationFunc = () => ({
screenInterpolator: (sceneProps) => {
const { scene } = sceneProps;
const tabs = ['Home'];
if (tabs.indexOf(scene.route.routeName) !== -1) return null;
},
});
export default StackNavigator(
{
Login: {
screen: Login,
},
ForgotPassword: {
screen: ForgotPassword,
},
SignUp: {
screen: SignUp,
},
Home: {
screen: Home,
},
},
{
headerMode: 'none',
transitionConfig: customAnimationFunc,
navigationOptions: {
headerVisible: false,
},
initialRouteName: 'Home',
},
);
The only problem right now is nothing is animating. I'll edit the answer when few screens animate & tabs don't

Is it possible to show tab bar in a screen but the screen does not appear in the tab bar?

Let I have three screens.
Home
Profile
Settings
When the App starts, Home screen will show with two tab (Profile and Settings). I have used react-navigation for tab navigator. When Profile tab will be clicked, profile screen will show and if Settings tab will be clicked, Settings screen will show.
You can add a Navigation Object to another as screen. I tried to create a sample code according to your needs
const HomeScreen = createTabNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {
header: null,
tabBarLabel: 'Profile',
tabBarOnPress: ({ navigation }) => {
navigation.navigate('Profile')
}
}
},
Settings: {
screen: Settings,
navigationOptions: {
header: null
}
},
},
{
initialRouteName: 'HomeScreen',
lazy: true,
})
const HomeScreen = createStackNavigator({
Profile: {
screen: Profile,
navigationOptions: {
header: null
}
},
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
},
{
initialRouteName: 'Home',
lazy: true,
})

I don't have headers on my screens but i want to have header only on one screen

I use reactnavigation for navigation. I don't have headers on my screens but i want to have header only on one screen (especially back button).
This is my root navigator:
...
class RootNavigation extends Component {
props: Props;
render() {
const { isProfileSelect } = this.props;
const initialRouteName = currentRoute(isProfileSelect);
const RootStackNav = StackNavigator(
{
AppHome: { screen: TabBarNavigator },
SwitchProfile: { screen: SwitchProfileScreen },
Pin: { screen: PinScreen },
},
{
initialRouteName,
headerMode: 'none',
},
);
return <RootStackNav />;
}
}
...
there is headerMode: 'none', it does mean i haven't any header navigator it is good for screens AppHome,SwitchProfile but not for Pin i need back button on header. Because I have to go on SwitchScreen and there i can continue on Pin screen and from Pin screen i sometime need go back to SwitchScreen And i have no back button on IOS. I need set header only in pin screen.
this is navigationOptions for pin screen:
...
static navigationOptions = {
title: I18n.t('screens.pinScreen.navigationOptions.title'),
};
...
but changes haven't any effect
Can you help me to add header only on Pin screen?
Thank you
update:
SOLUTION
const RootStackNav = StackNavigator(
{
AppHome: {
screen: TabBarNavigator,
navigationOptions: {
title: 'Header title',
headerMode: 'screen',
header: null,
},
},
SwitchProfile: {
screen: SwitchProfileScreen,
navigationOptions: {
title: 'Header title',
headerMode: 'screen',
header: null,
},
},
Pin: {
screen: PinScreen,
navigationOptions: {
title: 'Header title',
headerMode: 'screen',
// header: null,
},
},
},
{
initialRouteName,
// headerMode: 'none',
},
);
My case was reverse of yours...
I wanted to disable the header on one screen so I added the following code in that particular screen.
export default class NoHeaderView extends Component {
static navigationOptions = { header: null }
...
//your constructor, render and other stuff
...
}//
Let me know if it works.