Reputation: 471
So I'm creating a new login screen that supports login, Oauth. I added some code from a generic login screen I made before but I am receiving a Type Error for my navigate prop. Can someone explain why this is occurring and how to fix it? My app won't even load up because of this error and even though the error says in APp.js: 56. Inside my app file I'm using jsx to call the logingscreen.
LoginScreen.js
import React from 'react';
import {
View,
Image,
Text,
Dimensions,
StyleSheet,
TouchableOpacity,
Alert,
Animated,
Easing,
TextInput } from 'react-native';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import { FontAwesome as Icon } from '@expo/vector-icons';
import FBSDK, { LoginManager } from 'react-native-fbsdk';
import { ifIphoneX } from 'react-native-iphone-x-helper';
import firebase from 'firebase';
import { AppAuth } from 'expo';
import Footer from '../Components/Footer';
import * as userActions from '../reducers/user/Actions';
import {
EMAIL_REGIX, //What is this EMAIL_REGIX?
EMAIL_ALERT,
PASSWORD_ALERT,
PASSWORD_MESSAGE,
FB_ALERT,
ACCOUNT,
FORGOT,
SIGNUP
} from '../utils/constants';
const { width, height } = Dimensions.get('window');
class LoginScreen extends React.Component {
onSubmit = () => {
const {
navigation: { navigate }
} = this.props;
if (!EMAIL_REGIX.test(this.state.email)) {
Alert.alert('Alert', EMAIL_ALERT);
} else if (this.state.password.length < 6) {
Alert.alert('Alert', PASSWORD_ALERT);
} else if (this.state.password.length > 15) {
Alert.alert('Alert', PASSWORD_MESSAGE);
} else {
navigate(ACCOUNT);
}
};
checkIfUserIsLoggedIn = () => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
this.props.navigation.navigate('Account');
} else {
this.props.navigation.navigate('LoginScreen');
}
});
};
render() {
const {
navigation: { navigate }
} = this.props;
return (
<View style={styles.container}>
<View style={{ ...StyleSheet.absoluteFill }}>
<Image
source={require('../assets/Images/TemplatePic.jpg')}
style={{ flex: 1, height: null, width: null }}
resizeMode="cover"
/>
</View>
<View style={{ height: height / 3, backgroundColor: 'white' }} />
<TouchableOpacity onPress={this.onSubmit}>
<View
style={[
styles.loginbutton,
commonStyles.alignSelfcenter,
{
width: width * 0.73
}
]}
>
<Text style={[styles.logintextbutton]}>Sign In</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
flex: 1,
backgroundColor: 'red',
justifyContent: 'flex-end'
},
loginbutton: {
width: 320,
backgroundColor: 'rgb(72, 244, 255)',
borderRadius: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.5,
shadowRadius: 5,
elevation: 20
},
logintextbutton: {
fontSize: 16,
textAlign: 'center',
justifyContent: 'center',
color: 'white',
fontFamily: 'Helvetica-Bold'
},
});
export default LoginScreen;
App.js
import React from 'react';
import { View, Image, Dimensions, SafeAreaView, StyleSheet, Text } from 'react-native';
import { Provider, connect } from 'react-redux';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import * as firebase from 'firebase';
import { firebaseConfig } from './config.js';
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();
});
}
export default class App extends React.Component {
// Render the app container component with the provider around it
constructor(props) {
super(props);
this.state = {
isReady: false
};
}
async _loadAssetsAsync() {
const imageAssets = cacheImages([
require('./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}>
<Provider store={store}>
<LoginScreen navigation={this.props.navigation} />
</Provider>
</View>
);
}
}
const styles = StyleSheet.create({
background: {
flex: 1,
backgroundColor: '#FFFFFF',
justifyContent: 'center',
alignItems: 'center',
fontSize: 16
},
textStyle: {
}
});
Upvotes: 0
Views: 456
Reputation: 5450
In your App.js
<LoginScreen navigation = {this.props.navigation}/>
In your loginScreen.js
<TouchableOpacity onPress={ () =>this.onSubmit()}>
Also,
checkIfUserIsLoggedIn = () => {
const that = this;
firebase.auth().onAuthStateChanged(user => {
if (user) {
that.props.navigation.navigate('Account');
} else {
that.props.navigation.navigate('LoginScreen');
}
});
};
This will resolve the issue :)
You need to pass the navigation to your child component to make them accessible.
Upvotes: 1