HeaderLeft onPress to open the drawer, undefined is not an object - react-native

I am having a problem with my line of code specifically with the headerLeft onPress. I wanted to put an icon where when pressed it will open the drawerNavigator of my simple application.
this is my AppNavigation.js
//DRAWER NAVIGATOR
const drawerNav = createDrawerNavigator({
JobFeed: {
screen: MainScreen,
navigationOptions: {drawerLabel: 'Job Feed',}
},
},
{
drawerPosition : "left", contentComponent: CustomDrawerComponent,
});
// Manifest of possible screens
const primaryNav = createStackNavigator({
LaunchScreen: {
screen: LaunchScreen,
navigationOptions: {
title: "Ty, Next",
headerTitleStyle: {
textAlign: 'center',
flex: 1,
fontFamily: 'CoreSansD65Heavy',
color: Colors.semiGray,
}
}
},
MainScreen: {
screen: MainScreen,
navigationOptions: {
title: "Ty, Next",
headerTitleStyle: {
textAlign: 'center',
flex: 1,
fontFamily: 'CoreSansD65Heavy',
color: Colors.semiGray,
marginBottom: 20,
}
}
},
},
{
// Default config for all screens
initialRouteName: 'MainScreen',
})
so here's the problem. In my MainScreen.js I put this code, whenever I press the button It is saying that undefined is not an object (evaluating _this2.props.navigation ) Please help me I am stuck on this particular matter..
static navigationOptions = ({ navigation }) => {
const { state } = navigation;
const {} = state;
return {
headerStyle:{
backgroundColor: "Transparent",
marginRight: 20,
marginLeft: 20,
},
headerLeft: (
<TouchableOpacity onPress={this.props.navigation.openDrawer()}>
<Icon name="bars" color={Colors.red} size={30}/>
</TouchableOpacity>
),
headerLeftStyle: styles.drawerIcon,
headerRight: (
<TouchableOpacity>
<Icon2 name="sc-telegram" color={Colors.red} size={30} />
</TouchableOpacity>
),
headerRightStyle: styles.planeIcon,
headerTransparent: true,
};
}
Also I can't even access my drawer navigator when swiping to right. Any Ideas why is this happening?

In your mainscreen.js is your component is class based component if it is try to create a fat arrow function instead of directly calling on onpress prop and call from that function and if your component is not class based make it first..!

Related

How to toggle the side menu bar in react native?

I am trying to create a new app. I have created the side menu. But side menu drawer not working if i am in the same screen.For example in the screenshot i am already in the home screen. Now if i click the home in the side menu there is no action. One more question now the side menu covers the whole screen height. I want to be display between the header and bottom tab navigator. Please help me image
const DashboardTabNavigator = createBottomTabNavigator( {
Home: HomeScreen,
WebMenu: WebMenuScreen,
Settings: SettingsScreen,
},
{
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
labelStyle: {
fontSize: 15
},
tabStyle: {
justifyContent: 'center'
},
showIcon: false
},
});
//MenuDrawer
export class MenuDrawer extends React.Component {
gotoHome = () => {
this.props.navigation.navigate('Home');
}
gotoWebMenu = () => {
this.props.navigation.navigate('WebMenu');
}
gotoSettings = () => {
this.props.navigation.navigate('Settings');
}
render() {
return(
<View style = {styles.container}>
<Text onPress={this.gotoHome} style = {styles.item} ><Ionicons name="md-home" size={20} /> Home</Text>
<Text onPress={this.gotoWebMenu} style = {styles.item} ><Ionicons name="logo-rss" size={20} /> Web Menu</Text>
<Text onPress={this.gotoSettings} style = {styles.item} ><Ionicons name="md-settings" size={20} /> Settings</Text>
</View>
)
}
}
//side menu
const MyApp = createDrawerNavigator({
Menu: {
screen: DashboardTabNavigator,
},
},
{
contentComponent: MenuDrawer,
drawerPosition: 'right',
drawerWidth:width - width/2
},
{
initialRouteName: 'Login'
});
//screen route
const LoginStack = createStackNavigator({
Login: {
screen: Login
},
Home:{ screen: MyApp},
}, {
initialRouteName: 'Login',
headerMode: 'null'
});
const MyApp1 = createAppContainer(LoginStack);
Try this.
class NavigationDrawerStructure extends Component {
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Image
source={require('../Img/hamburger.png')}
style={{ width: 25, height: 25, marginLeft: 20, tintColor: '#ffffff' }}
/>
</TouchableOpacity>
</View>
);
}
}
And then use it in this way
const HomeActivity_StackNavigator = createStackNavigator({
Home: {
screen: Main,
navigationOptions: ({ navigation }) => ({
title: 'Dashboard',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800'
},
headerTintColor: '#fff'
}),
},
}, {headerLayoutPreset: 'center'});

Share Navigation Options for Multiple Stack Navigator

Using react native with react navigation I use a DrawNavigator and several StackNavigators. Now I want to define the header style (header comes with StackNavigator) of the StackNavigator just once and for all StackNavigators.
This is what i have:
// View1.js
export default StackNav1 = createStackNavigator(
{
View1: View1Screen,
View2: View2Screen
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#9eb9b3',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
headerLeft: (
<Icon style={{ paddingLeft: 10 }} name="bars" size={30}
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
/>
),
}
}
}
)
// View2.js
export default StackNav2 = createStackNavigator(
{
View3: View3Screen,
View4: View4Screen
},
// here I need to define the style from View1.js again ?!
)
Is there a smarter solution to share the appearance than writing it over and over again.
When the app is scaling I probably will have a lot StackNavigators and want them to have the same header/appearance.
I appreciate your thoughts!
Create stackNavigatorConfig which is the second parameter of react navigation methods.
stackNavigatorConfig = {
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#9eb9b3'
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
},
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="bars"
size={30}
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
/>
)
};
}
};
Then you can use it like
export default StackNav1 = createStackNavigator({
View1: View1Screen,
View2: View2Screen
},
stackNavigatorConfig);
export default StackNav2 = createStackNavigator({
View3: View3Screen,
View4: View4Screen
},
stackNavigatorConfig);

how can I use constructor method with react navigation v3?

I need to use state on my App.js code but react-navigation v3 don't use class so I can't define the constructor method.
Is there any other way so I can use state?
I tried to use a boolean javascript variable but it didn't help.
I use StackNavigator, drawer navigator and DrawerNavigator and BottomTabNavigator like this
const TabAppNavigator = createBottomTabNavigator({
Posts: {
screen: PostsScreen,
navigationOptions: {
tabBarLabel: 'Posts',
tabBarIcon: ({ tintColor }) => (<Icon name="md-home" color={tintColor} size={25} />)
}
},
Tools: {
screen: ToolsScreen,
navigationOptions: {
tabBarLabel: 'Tools',
tabBarIcon: ({ tintColor }) => (<Icon name="md-apps" color={tintColor} size={25} />)
}
},
Favourite: {
screen: FavouriteScreen,
navigationOptions: {
tabBarLabel: 'Favourite',
tabBarIcon: ({ tintColor }) => (<Icon name="md-heart" color={tintColor} size={25} />)
}
},
}, {
initialRouteName: 'Posts',
order: ['Posts', 'Tools', 'Favourite'],
tabBarOptions: {
activeTintColor: '#d94854',
inactiveTintColor: '#818181',
style: {
backgroundColor: '#fff',
borderTopColor: '#818181',
borderTopWidth: 1,
paddingBottom: 5,
paddingTop: 15,
},
labelStyle: {
fontSize: 13,
marginTop: 10,
},
},
navigationOptions: ({ navigation }) => {
return {
headerTitle: 'Growth Hack Toolkit',
headerTintColor: '#fff',
headerStyle: {
backgroundColor: '#d94854',
},
headerLeft: (
<Icon name="md-menu" color="#fff" size={25} style={{ paddingLeft: 15 }} onPress={() => navigation.openDrawer()} />
),
headerRight: (
<Icon name="md-search" color="#fff" size={25} style={{ paddingRight: 15 }} onPress={() => search()} />
)
}
}
}
)
const PostsStackAppNavigator = createStackNavigator({
TabAppNavigator: TabAppNavigator,
Posts: { screen: PostsScreen },
Post: { screen: PostScreen }
})
const ToolsStackAppNavigator = createStackNavigator({
TabAppNavigator: TabAppNavigator,
Tools: { screen: ToolsScreen },
Tool: { screen: ToolScreen },
ToolList: { screen: ToolListScreen },
Web: { screen: WebScreen },
Mobile: { screen: MobileScreen },
})
const DrawerAppNavigator = createDrawerNavigator({
Posts: { screen: PostsStackAppNavigator },
Tools: { screen: ToolsStackAppNavigator },
About: { screen: AboutScreen },
}, {
contentComponent: SideMenu,
drawerWidth: 250,
})
const App = createAppContainer(DrawerAppNavigator);
export default App;
I want to change my header view based on my state
basically, I have a default header (the same header for all tab screens) that contains a title, menu icon to open the drawer navigation and search icon to start searching
what I need to do is that when search icon is pressed I will change my state to show the instead of the title and when close icon is pressed I will change the state to show my default header again.
after spending so much time searching for a solution or a workaround, the answer is: I cannot.
It is not possible to have state in a functional component. So I have to use react navigation v2 instead of v3 as it is implemented as class-based component.
These links could help to understand:
difference between functional and class-based React components
React State without Constructor

Drawer Navigator with Stack in React Native in Header

I have a confusion regarding React Navigation. I need a Login screen which don't have Drawer and in rest of application, I need drawer Navigation.
I am looking for a solution where I can write code in a single place and applicable on whole application.
So I have created one stack navigator which contains the path of
createStackNavigator({
LoginRT:{
screen:Login
},
HomeRT:{
screen:Home
},
ContactRT:{
screen:Contact,
navigationOptions: {
headerRight: (
<Text></Text>
)
}
},
HaulerSelectionRT:{
screen:HaulerSelection
}
},
{
initialRouteName: 'LoginRT',
/* The header config from HomeScreen is now here */
defaultNavigationOptions : ({ navigation}) => ({
headerStyle: {
backgroundColor: "#3B9EC1",
color: 'white',
fontSize: 16,
},
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 20,
textAlign:"center",
flex:1
},
// headerRight: (
// <Icon
// size={30}
// name="bars"
// style={{ paddingRight: 5 }}
// onPress={() => navigation.openDrawer()}
// />
// ),
// headerLeft: <Text onPress={() =>
// navigation.navigate('LoginRT')}>Menu</Text>,
headerTintColor: "#fff",
animationEnabled: true
})
}
);
and one for Drawer Navigation
const DrawerStack = createDrawerNavigator(
{
LoginRoute: Login,
Hauler: HaulerSelection,
},
{
initialRouteName: 'LoginRoute',
drawerPosition: 'left',
// navigationOptions: {navigationOptions
// },
}
);
and then I register both in Appcontainer
const AppContainer = createAppContainer(MyRoutes,DrawerStack);
But DrawerNavigation is not working.
My doubt is, Is my approach is right? Or there is another way to achieve same.
Please help.
The header part is added by default and is avoidable.
You can use the following code to achieve this.
navigationOptions: {
header: null
}
This navigation options could either be screen specific or common to all screens.

Custom View as background for StackNavigator

I need use one image below stack navigator or something like this.
Into StackNavigator I can set backgroundColor, opacity (view style) etc. But no possibility to set one background image or custom view component. Also if set to each screen its not good for screen translation.
I was try to wrap like this:
<ImageBackground>
<MyStackNavigator/>
</ImageBackground/>
No results.
Can you help me? +1 for any try
I found a solution
Navigator:
const AuthStackNavigator = StackNavigator({
LANDING: {
screen: LandingScreen
},
SIGN_IN: {
screen: SignInScreen
},
{
mode: 'card',
cardStyle: { backgroundColor: 'transparent' },
transitionConfig: () => ({
containerStyle: {
backgroundColor: 'transparent',
}
}),
initialRouteName: 'LANDING',
}
);
Render:
render() {
return <ImageBackground
style={{
width: null,
height: null,
backgroundColor: 'transparent',
flex: 1,
}}
source={landing_background}
>
<AuthStackNavigator
ref='navigator'
/>
</ImageBackground>
}