React native navigation parameter not working with Switch navigator - react-native

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.

Related

How do I conditionally render a header in a Stack Navigator for React Native Navigation?

I would like my initial page to NOT contain a header. However, I would like a header to appear on each subsequent page. Right now my current stackNavigator looks like this:
const AppNavigator = createStackNavigator(
{
HomeScreen: HomePage,
SecondPage: SecondPage,
Account: Account,
About: About,
},
{
initialRouteName: 'HomeScreen',
headerMode: 'none',
navigationOptions: {
headerVisible: false,
},
},
);
export default createAppContainer(AppNavigator);
Here is the basic boilerplate for my second page:
const SecondPage: () => React$Node = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<View style={styles.body}>
<View style={styles.sectionContainer}>
<Text style={styles.sectionTitle}>This is the Secondpage</Text>
</View>
</View>
</>
);
};
export default SecondPage;
You have three ways of doing this using navigationOptions:
1) Directly when you define your navigator:
createStackNavigator({
{
HomeScreen: {
screen : HomePage,
navigationOptions: {header : null}
},
SecondPage: SecondPage,
Account: Account,
About: About,
},
{ ... } //your navigationOptions
})
2) Directly inside the screen as said by Shashank Malviya. Only if you aren't using a functional component.
3) Return defaultNavigationOptions as a function and use navigation state:
createStackNavigator({
{ ... }, //your RouteConfigs
{
initialRouteName: 'HomeScreen',
headerMode: 'none',
defaultNavigationOptions : ({navigation}) => navigation.state.routeName === "HomePage" && {header: null}
},
})
Can be written on every component before render
static navigationOptions = ({ navigation }) => {
const { state } = navigation
return {
headerVisible: true // can be true or false
}
}

How to select conditional createStackNavigator screen?

I'm trying to select conditional screen based on Redux data. I have two screens in a screen stack, and this screen stack is also a part of TabNavigator (Logged out screen should be shown with Tabs too). If user is logged in, I need to show CheckScreen, otherwise CheckScreenLoggedOut. I tried setting initialRouteName conditionally but it shows CheckScreenLoggedOut only after logging in.
How can I implement this logic?
Here is my createStackNavigator part:
const CheckScreenStack = createStackNavigator(
{
CheckSendLoggedOut: {
screen: IntroScreen,
navigationOptions: ({navigation}) => ({
headerLeft: (
<View>
<TestModeIcon/>
</View>
),
}),
},
CheckScreen: {
screen: CheckScreen,
navigationOptions: ({navigation}) => ({
headerRight: (
<View>
<TouchableOpacity title='' onPress={() => { navigation.navigate('NotificationsScreen'); }}>
<NotificationTabBarIcon/>
</TouchableOpacity>
</View>
)
}),
},
},
{
initialRouteName: (typeof store.getState().userData !== "undefined") ? 'CheckScreen' : 'CheckSendLoggedOut'
}
);
I have already achieved this by accessing the redux state with connect, you can do something like this:
const CheckScreenStack = ({ userData }) => {
const Stack = createStackNavigator(
{
...
},
{
initialRouteName: (typeof userData !== "undefined") ? 'CheckScreen' : 'CheckSendLoggedOut'
}
);
return Stack;
}
const mapStateToProps = ({ userData }) => {
return { userData };
};
export default connect(
mapStateToProps,
{},
)(CheckScreenStack);

How to navigate from login screen to home screen that contains the bottom tabs

Please help , im not sure how to make this work,
I dont know how to navigate from the login page to the home screen that will contain tabs, i only know how to navigate from the login to the home screen, but without the bottom tabs.
The error i get is: The component for route 'App'must be a React component.
const HomeStack = createStackNavigator(
{
//Defination of Navigaton from home screen
Home: { screen: HomeScreen },
ViewBookings: {
screen: ViewBookingsScreen,
navigationOptions: {
//Header customization of the perticular Screen
headerStyle: {
backgroundColor: '#0892d0',
},
headerTintColor: '#FFFFFF',
title: 'View All Bookings',
//Header title
},
},
},
{
defaultNavigationOptions: {
//Header customization of the perticular Screen
headerStyle: {
backgroundColor: '#0892d0',
},
headerTintColor: '#FFFFFF',
title: 'Welcome, User',
//Header title
},
}
);
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
const App = createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: TabStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
);
const TabStack = createBottomTabNavigator(
{
Home : { screen: HomeStack },
Bookings: { screen: BookingStack},
Reminders: { screen: ReminderStack},
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, horizontal, tintColor }) => {
const { routeName } = navigation.state;
let IconComponent = Ionicons;
let iconName;
if (routeName === 'Home') {
iconName = `ios-home`;
} else if (routeName === 'Bookings') {
iconName = `ios-book`;
} else if (routeName === 'Reminders') {
iconName = `ios-alarm`;
}
return <IconComponent name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: '#0892d0',
inactiveTintColor: 'gray',
},
}
);
export default createAppContainer(App);
Once you authentication is successful you must call
this.props.navigation.navigate("Home");
This will navigate user to home screen.
You can decide route as per your requirement
In Your Home Screen If you are importing your Login Component like
import {Whatever} from 'Wherever'
Change it to
import Whatever from 'Wherever'
Try by removing curly braces. Because as i see you have used Default with export. So when we used default we dont use braces while importing.

Header not working in createSwitchNavigator

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

Change tab navigator name and header

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