React Native Drawer Navigator props undefined - reactjs

I am trying to create a drawer navigator, I believe I am doing everything correct but I am getting this error when I try to open the drawer undefined is not an object (evaluating '_this2.props.navigation.navigate'). I did some console logs and found that this.props is empty for every class, including the class in App.js, even after I register the screens. Can someone please help or see if this is an actual bug?
Thanks in advance
How to reproduce
App.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
import Home1 from './home';
// You can import from local files
import AssetExample from './components/AssetExample';
import Nav from './nav';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { createDrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
console.log(this.props);
return (
<View style={styles.container}>
<Home1 {...this.props} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
home.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { DrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class Home1 extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
static navigationOptions = {
drawerLabel: 'Home'
};
render() {
return (
<View style={styles.container}>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
console.log(this.props);
console.log(this.props.navigation);
this.props.navigation.navigate('DrawerToggle');}}>
<Icon name="md-menu" size={30} />
</TouchableOpacity>
</View>
<Text> 'hi' </Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
screen.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { DrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
export default class Map extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
static navigationOptions = {
drawerLabel: 'Map'
};
render() {
return (
<View>
<StatusBar barStyle="dark-content" />
<View style={styles.header}>
<TouchableOpacity
onPress={() => {
console.log(this.props);
console.log(this.props.navigation);
this.props.navigation.navigate('DrawerToggle');}}>
<Icon name="md-menu" size={30} />
</TouchableOpacity>
<Text> 'hello' </Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: StatusBar.currentHeight,
backgroundColor: '#FFF',
},
innerContainer: { flex: 1, alignItems: 'center', justifyContent: 'center' },
header: { padding: 15, paddingTop: 22 },
});
nav.js
import * as React from 'react';
import { Text, View, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import { Constants } from 'expo';
import Map from './screen'
import Home1 from './home';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
import { Ionicons as Icon } from '#expo/vector-icons';
import { createDrawerNavigator, DrawerItems, Navigation } from 'react-navigation';
const Nav = createDrawerNavigator({
Home: {
screen: Home1
},
Map: {
screen: Map
},
});
export default Nav;
Your Environment
"react-native-paper": "2.1.3",
"react-navigation": "2.18.2"
Running code online here https://snack.expo.io/

navigation.navigate('DrawerToggle') was removed in v2.
You can use
this.props.navigation.openDrawer();
this.props.navigation.closeDrawer();
to open and close the drawer respectively.
Please refer to https://reactnavigation.org/docs/en/drawer-based-navigation.html

Related

How do I create stack navigation tabs for a separate .tsx file in react js

At the start of my application, there is two tabs at the bottom of the screen (these tabs came in the template I downloaded from Expo for react js). I made a new screen, called homepage, and I want to now replicate those same tabs at the bottom, but I can't figure out how. I tried using a stack navigator but it did not work.
I want it to look like this
Here is my code for homescreen
import * as React from 'react';
import { StyleSheet, Button, TextInput } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import FAQ_Screen from './FAQ_Screen';
import NewsScreen from './NewsScreen';
import { createStackNavigator } from '#react-navigation/stack';
import BottomTabNavigator from '../navigation/BottomTabNavigator';
import NotFoundScreen from './NotFoundScreen';
const Stack = createStackNavigator();
export default function HomeScreen() {
return (
<View style={styles.container}>
<Text> Home </Text>
<select>
<option> Station 1 </option>
<option> Staton 2 </option>
</select>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
});
You should declare tabs inside Tab.Navigator.
These screens can be separate .tsx or js files. I did using js, to be able to show using Expo. However, ts/js doesn't change the behavior.
I did a working example:
https://snack.expo.io/#mayconjcm/tab-navigation-%7C-react-navigation
You can also see the code here:
Home:
import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import HomeTab from './Tab1';
import SettingsTab from './Tab2';
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeTab} />
<Tab.Screen name="Settings" component={SettingsTab} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyTabs />
</NavigationContainer>
);
}
Tab1:
import * as React from 'react';
import { Text, View } from 'react-native';
const HomeTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
export default HomeTab;
Tab2:
import * as React from 'react';
import { Text, View } from 'react-native';
const SettingsTab = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
export default SettingsTab;

React Native Expo: Why isn't/can't my image can't be found and isn't loading?

I'm building a React Native App with expo and I have an image I want to display on my login screen that should cover the whole image but for some reason it's not loading and I have a blank screen. My terminal says "Could not find image file:///Users/BlahBlah/Library/Developer/CoreSimulator/Devices/3FE078A1-2C0A-4308-B256-BFBF1B246A85/data/Containers/Bundle/Application/08978CAA-74FC-476D-939C-9CBDF1E4B9D9/Exponent-2.13.0.app/./assets/Images/TemplatePic.jpg
- node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:104:55 in
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:414:4 in __invokeCallback
- ... 4 more stack frames from framework internals"
LoginScreen
import React from 'react';
import { View, Image, Dimensions, SafeAreaView, StyleSheet, Text } from 'react-native';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import { Tab, Tabs, Header } from 'native-base';
import { commonStyles } from './styles/styles';
import SignInScreen from './SignInScreen';
import SignUp from './SignUp';
const { width, height } = Dimensions.get('window');
class LoginScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
isReady: false
};
}
render() {
return (
<View style={styles.background}>
<View style={StyleSheet.absoluteFill}>
<Image
source={('../assets/Image/TemplatePic.jpg')}
style={{ flex: 1, height: null, width: null }}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: '#FFFFFF',
justifyContent: 'center',
alignItems: 'center',
}
});
export default LoginScreen;
App.js
import React from 'react';
import { View, Image, Dimensions, SafeAreaView, StyleSheet, Text } from 'react-native';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import * as firebase from 'firebase';
import { firebaseConfig } from './config.js';
import { Provider, connect } from 'react-redux';
import RootStack from './RootStack';
import LoginScreen from './App/screens/LoginScreen';
import configureStore from './App/reducers/configureStore';
firebase.initializeApp(firebaseConfig);
// create store from redux
const store = configureStore();
function cacheImages(images) {
return images.map(image => {
if (typeof image === 'string') {
return Image.prefetch(image);
}
return Asset.fromModule(image).downloadAsync();
});
}
const { width, height } = Dimensions.get('window');
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isReady: false
};
}
async _loadAssetsAsync() {
const imageAssets = cacheImages([
('./assets/Images/TemplatePic.jpg'),
]);
await Promise.all([...imageAssets]);
}
render() {
//If the state is not ready then display the apploading oterwise display the app
if (!this.state.isReady) {
return (
<AppLoading
startAsync={this._loadAssetsAsync}
onFinish={() => this.setState({ isReady: true })}
onError={console.warn}
/>
);
}
return (
<View style={styles.background}>
<LoginScreen />
</View>
);
}
}
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: '#FFFFFF',
justifyContent: 'center',
alignItems: 'center',
fontSize: 16
},
textStyle: {
}
});
Try this:
<Image
source={require('../assets/Image/TemplatePic.jpg')}
style={{ flex: 1 }}
resizeMode="cover"
/>

TSlint and React: How to enforce styles at bottom before export default?

I'm building a React Native app with TypeScript. I'm currently configuring my TSLint file.
Is there a way to enforce styles in the same document to be at the bottom of the file (before the exports)?
E.g. MyComponent.tsx:
import React, { Component } from "react";
import { StyleSheet, Text } from "react-native";
import { SafeAreaView } from "react-navigation";
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
}
});
export class MyComponent extends Component {
render() {
return (
<SafeAreaView style={styles.container}>
<Text>This screen is my component.</Text>
</SafeAreaView>
);
}
}
export default MyComponent;
Should throw an error, whereas:
import React, { Component } from 'react';
import { StyleSheet, Text } from 'react-native';
import { SafeAreaView } from 'react-navigation';
export class MyComponent extends Component {
public render() {
return (
<SafeAreaView style={styles.container}>
<Text>This screen is my component.</Text>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
alignItems: 'center',
flex: 1,
justifyContent: 'center'
}
});
export default MyComponent;
should pass?

React native open an activity

I am an Android developer who works with Android Studio most.
I started with my first react-native project for iOS and I want to know how is it possible to have one screen with a button that when the user clicks takes him to another screen (or activity in an android way) which has a hello message.
I would be really obliged to anyone that can help because I am really new to React and React-Native.
I have tried the following code but I get the following error.
My code is the following:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, Button } from 'react-native';
import { createStackNavigator } from 'react-navigation';
import Settings from './Settings';
import Home from './Home';
const AppNavigator = createStackNavigator({
HomeScreen: { screen: Home },
SettingScreen: { screen: Settings },
});
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Image style={styles.image} source={require('./assets/adc.png')} />
<Text style={styles.adc}>Aratos Disaster Control</Text>
<Button title="Settings" onPress = {() => this.props.navigation.navigate('SettingScreen')} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
adc:{
fontWeight: 'bold',
marginTop: 20
},
image:{
width: 80,
height: 100
}
});
// Home.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export class Home extends Component {
render() {
return (
<View>
<Text>This is the home screen</Text>
<Button title="Settings" onPress={() => this.props.navigation.navigate('SettingScreen')} />
</View>
)
}
}
export default Home
// Settings.js
import React, { Component } from 'react';
import { View, Text, Button } from 'react-native';
export class Settings extends Component {
render() {
return (
<View>
<Text>This is the Settings screen</Text>
</View>
)
}
};
export default Settings;
For navigate between pages, you can use React Navigation or react-native-router-flux or other packages. You have to define the structure of your navigation and then navigate to each page using this packages. Read guides for more information.

React native stack navigation goBack() not working

I created common header for all pages, so create header component then i include that header in signup.js component goback navigation function working in signup.js page but not working header component getting undefined object navigate.goback error
Anyone give a solution for that like that i include component
sample code:
import React from 'react';
import { StyleSheet, Text, View, Image, ScrollView, TextInput,KeyboardAvoidingView, StatusBar } from 'react-native';
import {Icon,Body,Button,Title,Left,Right} from 'native-base';
import Expo from "expo";
import { Constants } from 'expo';
import Headerbar from "./../Header/header";
import Statusbar from "./../statusbar";
const googleIcon=require('../../../img/google_icon.png');
const fbIcon=require('../../../img/fb_icon.png');
export default class Socialsignup extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
render() {
return (
<ScrollView style={styles.socialContainer} scrollEnabled={true}>
<Statusbar/>
<Headerbar title="Social Login" />
<View style={styles.socialText}>
<Text style={styles.accountText}>Choose an account</Text>
</View>
<View style={styles.socialIconsBase}>
<View style={styles.socialIconsGoogle}>
<Image source={googleIcon} style={styles.googleIcon}/>
<Text style={styles.iconText}>
Google
</Text>
</View>
<View style={styles.socialIconsGoogle}>
<Image source={fbIcon} style={styles.fbIcon}/>
<Text style={styles.iconText}>
Facebook
</Text>
</View>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
socialContainer: {
backgroundColor: '#fff',
},
accountText: {
marginTop:25,
fontSize:20,
padding:20
},
socialIconsBase:
{
flexDirection:'row',
flex:1,
marginTop:40,
borderBottomWidth:1,
borderBottomColor:'#a8c0ce'
},
socialIconsGoogle:
{
flex:1,
alignItems:'center',
paddingTop:25,
paddingBottom:25,
borderRightWidth:1,
borderRightColor:'#a8c0ce',
marginBottom:8,
},
fbIcon:{
height:50,
width:50,
},
googleIcon:{
height:50,
width:50,
},
iconText:{
fontSize:15,
marginTop:15
}
});
you need to use this inside the header component :
import { withRouter } from 'react-router'
and then instead of export default HeaderClassName
use export default withRouter(HeaderClassName)
and you can go back by this.props.history.goBack()
You need to use this too:
<BrowserRouter>
<App />
and then add the pages like that
<Route path='/page' component={Page} />

Resources