The component for route app must be a react component - navigation-drawer

I have below code base
Getting this error
The component for route app must be a react component
I saw many questions like this on SO, and solutions there but being a beginner not able to resolve yet, tried with adding export / export default with each class
but not working
https://snack.expo.io/#mparvez19861/drawer-navigation?session_id=snack-session-hyLuO4xPa
import React, { Component } from 'react';
import { View, Text, TouchableHighlight, Image } from 'react-native';
import { createDrawerNavigator } from 'react-navigation';
import {
ActivityIndicator,
AsyncStorage,
Button,
StatusBar,
StyleSheet
} from 'react-native';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from
'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons'
class HeaderNavigationBar extends Component {
render() {
return (
<View style={{
height: 70,
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center'
}}>
<TouchableHighlight style={{ marginLeft: 10, marginTop: 15 }}
onPress={() => { this.props.navigation.openDrawer() }}>
{/* <Image
style={{ width: 32, height: 32 }}
source={{uri: 'https://png.icons8.com/ios/2x/menu-filled.png'}}
/> */}
<Icon name='md-menu' size={35} />
</TouchableHighlight>
</View>
);
}
}
export class HomeScreen extends Component {
render() {
return (
<View style={{
flex: 1,
flexDirection: 'column',
}}>
<HeaderNavigationBar {...this.props} />
<View style={{
flex: 1,
backgroundColor: '#4885ed',
alignItems: 'center',
justifyContent: 'center'
}}>
<Text style={{ fontWeight: 'bold', fontSize: 22, color: 'white' }}>
This is Home Screen
</Text>
</View>
</View>);
}
}
export class InfoScreen extends Component {
render() {
return (<View style={{
flex: 1,
flexDirection: 'column',
}}>
<HeaderNavigationBar {...this.props} />
<View style={{
flex: 1,
backgroundColor: '#4734ac',
alignItems: 'center',
justifyContent: 'center'
}}>
<Text style={{ fontWeight: 'bold', fontSize: 22, color: 'white' }}>
This is Info Screen
</Text>
</View>
</View>);
}
}
class SignInScreen extends React.Component {
static navigationOptions = {
title: 'Please sign in',
};
render() {
return (
<View style={styles.container}>
<Button title="Sign in!" onPress={this._signInAsync} />
</View>
);
}
_signInAsync = async () => {
await AsyncStorage.setItem('userToken', 'abc');
this.props.navigation.navigate('App');
};
}
class AuthLoadingScreen extends React.Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await AsyncStorage.getItem('userToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
const drNav = createDrawerNavigator(
{
Home: {
screen: HomeScreen
},
Info: {
screen: InfoScreen
}
}
)
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: drNav,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
Any help appreciated
Thanks

Related

Using FlatList to display custom card elements and need to make them touchable

I need to make the list of items touchable in a flatlist, but have no idea how to make the individual components touchable so i can access the id of that flatlist item. I need to handle the onPress so I can use react navigation 5 to send the users to a different screen.
I'm using an array of data to create a card like component that renders in the flatlist.
how do I make the individual list items touchable?
here's what I'm working with:
import * as React from "react";
import { View, StyleSheet, FlatList, SafeAreaView } from "react-native";
import BigButton from "../components/BigButton.js";
import HomeScreenImage from "../components/HomeScreenImage.js";
import HomeCard from "../components/Card";
const homeOptions = [
{
name: "Beast shedule",
body: "Create and manage your workout shedule",
image: require("../assets/images/DoubleBis.jpg"),
id: "1",
},
{
name: "Pre-Made Workouts",
body: "Use one of our pre-made workouts",
image: require("../assets/images/ChickA.jpg"),
id: "2",
},
{
name: "Statistics",
body: "Analyse your personal statistics",
image: require("../assets/images/WorkoutInProgress.jpg"),
id: "3",
},
{
name: "History",
body: "Keep track of your workout history",
image: require("../assets/images/ChickH.jpg"),
id: "4",
},
];
const HomeScreen = (props) => {
return (
<View style={Styles.containerTop}>
<View>
<HomeScreenImage style={Styles.top} />
<View style={Styles.top}>
<BigButton title="Train & Track" />
</View>
</View>
<SafeAreaView style={Styles.flatListContainer}>
<FlatList
data={homeOptions}
renderItem={({ item }) => {
return <HomeCard info={item} />;
}}
keyExtractor={(homeOption) => homeOption.id}
showsVerticalScrollIndicator={false}
/>
</SafeAreaView>
</View>
);
};
const Styles = StyleSheet.create({
containerTop: {
flex: 1,
backgroundColor: "#3E3636",
},
top: {
flex: 1,
height: "1%",
alignItems: "center",
justifyContent: "center",
},
flatListContainer: {
flex: 1,
},
});
export default HomeScreen;
import React from "react";
import { View, Text, StyleSheet, Dimensions, Image } from "react-native";
const HomeCard = (props) => {
return (
<View style={Styles.container}>
<View style={Styles.cardContainer}>
<Image style={Styles.imageStyle} source={props.info.image} />
<View style={Styles.infoStyle}>
<Text style={Styles.titleStyle}>{props.info.name}</Text>
<Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
</View>
</View>
</View>
);
};
const deviceWidth = Math.round(Dimensions.get("window").width);
const offset = 25;
const radius = 20;
const Styles = StyleSheet.create({
container: {
width: deviceWidth - 20,
marginTop: 20,
},
cardContainer: {
margin: 10,
width: deviceWidth - offset,
backgroundColor: "#000",
height: 200,
borderRadius: radius,
shadowColor: "#000",
shadowOffset: {
width: 5,
height: 5,
},
shadowOpacity: 0.75,
shadowRadius: 5,
elevation: 3,
},
imageStyle: {
height: 130,
width: deviceWidth - 25,
borderTopLeftRadius: radius,
borderTopRightRadius: radius,
opacity: 0.95,
},
titleStyle: {
color: "#F5EDED",
textAlign: "center",
fontSize: 20,
fontWeight: "800",
},
bodyTextStyle: {
fontWeight: "200",
color: "#F5EDED",
textAlign: "center",
},
infoStyle: {
marginHorizontal: 10,
marginVertical: 1,
},
});
export default HomeCard;
You can wrap your card with some touchable component, like TouchableOpacity for example, with naviagtion.navigate('routeName', {params}) function on onPress prop.
const HomeCard = (props) => {
return (
<TouchableOpacity onPress={() => navigation.navigate('ReceiverRoute', {image: props.info image, name: props.info.name })}> ///etc any parameters you want
<View style={Styles.container}>
<View style={Styles.cardContainer}>
<Image style={Styles.imageStyle} source={props.info.image} />
<View style={Styles.infoStyle}>
<Text style={Styles.titleStyle}>{props.info.name}</Text>
<Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
</View>
</View>
</View>
</TouchableOpacity>
);
};
and then you navigate to a component that can receive some params.
For a cleaner example you can look into docs. The main idea is just wrapping your card into some touchable with onpress navigation. For the navigation prop, you can either pass it to your card from parent component, or use useNavigation hook

facing problems with styling on react native and achieving a better responsive layout

I tried to run my code on various screen sized emulators and the layout of my design varies from device to device. I need help to make the layout more responsive and fixed on different sized screens such as tablets, 3"mobile and 6"mobile.
-----------or connect with us on----------- I want to style this line in better way and that remains the same look on every device
I tried using the dimensions of the screen by defining the width and height using variables, and by describing the values in percentages, but nothing worked.
import React, { Component } from 'react';
import { View,TouchableOpacity, Text, StyleSheet, Image, Dimensions } from 'react-native';
import BacgroundImage from './BackgroundImage';
import Buttons from './Reusable/Button';
const { width: WIDTH } = Dimensions.get('window');
class LaunchScreen extends Component {
render() {
return (
<BacgroundImage>
<View style={styles.logoContainer}>
<Image
source={require('./images/logo.png')}
style={styles.PlaceLogo}
/>
</View>
<View style={styles.Buttons}>
<Buttons style={styles.signupButton}
onPress={() => navigate('Login')}>
<Text style={styles.buttonText}> SIGN UP</Text>
</Buttons>
<Buttons style={styles.loginButton}>
<Text style={styles.buttonText}> SIGN IN</Text>
</Buttons>
</View >
<View style={styles.sepratorView}>
<Text style={styles.sepratorText}>--------- or connect with us on ---------</Text>
</View >
<View style={styles.socialButtonStyle}>
<TouchableOpacity
style={styles.fbstyle}
activeOpacity={0.5}
>
<Image
source={require('./images/facebookicon.png')}
style={styles.iconstyle}
/>
<View
style={styles.sepratorLine}
/>
<Text
style={styles.socialButtonText}
>FACEBOOK</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.googlestyle}
onPress={this.signIn}
activeOpacity={0.5}
>
<Image
source={require('./images/google.png')}
style={styles.iconstyle}
/>
<View
style={styles.sepratorLine}
/>
<Text style={styles.socialButtonText} >GOOGLE</Text>
</TouchableOpacity>
</View>
</BacgroundImage>
);
};
}
const styles = StyleSheet.create({
logoContainer: {
flex: 1
},
PlaceLogo: {
width: WIDTH - 140,
margin: 75,
resizeMode: 'center',
justifyContent: 'center',
alignItems: 'center',
},
yosoButtons: {
width: WIDTH - 80,
justifyContent:'center',
marginTop:350
},
signupButton: {
height:40,
paddingTop:7,
marginBottom: 15,
},
loginButton: {
height:40,
paddingTop:7,
marginBottom: 15
},
buttonText: {
},
sepratorText: {
textAlign:'center',
fontSize:20,
color: '#b6b7ba',
},
sepratorView: {
flexDirection: 'row',
justifyContent:'center',
alignItems:'center'
},
socialButtonStyle:{
flex:1,
flexDirection:'row',
justifyContent:'center',
alignItems:'center',
margin:5
},
fbstyle:{
flex:1,
flexDirection:'row',
borderColor:'white',
alignItems:'center',
backgroundColor:'#485a96',
borderWidth:1,
borderRadius:35,
height: 40,
marginLeft:15,
marginRight:15
},
googlestyle:{
flex:1,
flexDirection:'row',
alignItems:'center',
backgroundColor:'#dc4e41',
borderWidth:1,
borderRadius:35,
borderColor:'white',
height: 40,
marginRight:15
},
iconstyle:{
resizeMode:'stretch',
height:25,
width:25
},
sepratorLine:{
backgroundColor:'white',
width:2,
height: 40
},
socialButtonText:{
color: '#fff',
flex:1,
textAlign: 'center',
fontSize: 15,
fontWeight: "bold"
}
});
export default LaunchScreen;
I want the layout to remain the same. Both the logo and buttons remain at the same position on every device display.
And I want a better dynamic solution for separator I have used in code
--------------or connect with us on-----------
I got a workaround solution for this problem. I am assigning values using the height and width of the screen to the styling.
import { StyleSheet, Dimensions } from 'react-native';
const { width: WIDTH, height: HEIGHT } = Dimensions.get('window');
SomeText: {
fontSize: HEIGHT / 38,
marginTop: WIDTH / 20,
}

How to use secureTextEntry in tcomb-form-native?

I am using tcomb-form-native version 0.6.15 for form validation in react-native Version0.55.4 . When I use password field text should be hidden inside dots. As per docs I used secureTextEntry and set it to true but it is still showing the data like a simple text. I found some suggestion to use temple but i don't know how to use them.
Below is the Form code
const Form = t.form.Form;
t.form.Form.stylesheet.controlLabel.normal = {color: 'white'}
console.log(t.form.Form.options)
const User = t.struct({
name: t.String,
email: t.String,
password: t.String,
});
const formStyles = {
...Form.stylesheet,
formGroup: {
normal: {
marginBottom: 10,
color: 'white'
},
},
controlLabel: {
normal: {
fontSize: 12,
marginBottom: 7,
fontWeight: '600',
},
// the style applied when a validation error occours
error: {
color: 'red',
fontSize: 18,
marginBottom: 7,
fontWeight: '600',
},
},
};
const options = {
order: ['name', 'email', 'password' ],
fields: {
name: {
placeholder: 'Enter Name',
error: 'Name is empty?',
},
email: {
placeholder: 'Enter Email',
error: 'Email is empty?',
},
password: {
placeholder: 'Enter Password',
error: 'Password is empty?',
secureTextEntry: true,
template: (locals) => textbox(locals, )//here i can use template but don't know how
},
},
stylesheet: formStyles,
};
class SignupScreen extends Component{
static navigationOptions = {
header: null
};
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
password: '',
dateOfBirth: '',
};
}
onSubmit(){
const value = this._form.getValue();
console.log('value: ', value);
}
render(){
console.log(this.state.dateOfBirth)
return(
<ImageBackground
source={require('../../images/splash_screen.jpg')}
style={{flex: 1}}
>
<View style={styles.container}>
<View style={{flex:3, justifyContent: 'center', alignItems: 'center'}}>
<Image source={require('../../images/big_transparent_logo.png')} />
<Text style={styles.subtitleStyle}>Get free drink everyday</Text>
</View>
<View style={{ flex: 7, justifyContent: 'flex-start', alignSelf: 'center', alignItems: 'center', width: '80%'}}>
<View style={{width: '100%', paddingHorizontal: 10, paddingVertical: 10 , backgroundColor: 'rgba(0,0,0,0.6)'}}>
<Form ref={c => (this._form = c)} type={User} />
<TouchableOpacity style={{width: '100%', marginVertical: 10}} >
<Label title="BIRTHDAY" />
<DatePicker
style={{width: '100%'}}
date=''
mode="date"
placeholder={this.state.dateOfBirth}
format="DD-MM-YYYY"
maxDate="2002-06-01"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
showIcon={true}
androidMode='spinner'
customStyles={{
dateInput: {
marginLeft: 0,
borderWidth: 0,
textAlign: 'left',
color: 'white',
backgroundColor: '#f2f2f2',
paddingVertical: 0,
height: 30,
color: 'black'
}
// ... You can check the source to find the other keys.
}}
onDateChange={(date) => {this.setState({dateOfBirth: date})}}
/>
</TouchableOpacity >
<Button block bordered light
style={{ width: '47%', borderRadius: 5, alignSelf: 'center', height: 50}}
onPress={this.onSubmit.bind(this)}
>
<Text style={{color: 'white'}}>Sign Up</Text>
</Button>
<Button block light
style={{ width: '47%', borderRadius: 5, alignSelf: 'center', height: 50, backgroundColor: 'rgba(0,0,0,0)',}}
onPress={()=>this.props.navigation.goBack()}
>
<Text style={{color: 'white'}}>Back</Text>
</Button>
</View>
</View>
</View>
</ImageBackground>
);
}
}
export { SignupScreen };
Your form is not connected to the options variable. Call options in your form tag as in below.
<Form ref={c => (this._form = c)}
type={User}
options={options} //set form options
/>
It should work without a template.
password: {
password: true,
secureTextEntry: true}
}

React Native Animation Resize

React Native Animation does not scale. Animation is bigger. My code:
import { DangerZone } from 'expo';
const { Lottie } = DangerZone;
Styles:
animationContainer: {
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',z
},
View:
<Lottie
ref={(animation) => {
this.animation = animation;
}}
resizeMode="contain"
loop={Boolean(true)}
style={{
width: 300,
height: 30,
backgroundColor: '#ccc',
}}
source={this.state.animation}
/>
App screenshot
I don`t know why this does not work. Please help me

How to render an svg image in the front of background image on react native?

I want to render an svg image on the 'front layer' of an background image.
When the view loads, only the background image appears, and i don't get any erros. Is the image even loading (at the background of the background)?
Here is what i've done so far:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
Image,
} from 'react-native';
import SVGImage from 'react-native-svg-image';
export default class ShowScreen extends Component {
render() {
return (
<View style={styles.container}>
<Image
source={require('../img/image.jpg')}
style={styles.backgroundImage}
blurRadius={1}>
<View style={styles.content}>
<SVGImage
style={{ width: 80, height: 80 }}
source={{uri:'https://fluent-panda.appspot.com.storage.googleapis.com/dumbbell.svg'}}/>
</View>
</Image>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
backgroundImage: {
flex: 1,
alignSelf: 'stretch',
width: null,
justifyContent: 'center',
},
content: {
alignItems: 'center',
}
});
Why the image is not appearing? I am using react-native.
I have my own component to do so:
import React from 'react';
import { View, Image } from 'react-native';
const BackgroundImage = (props) => {
const { container, image } = styles;
return (
<View style={container}>
<Image
style={[image,
{ resizeMode: props.resizeMode,
opacity: props.opacity}
]}
source={props.source}***strong text***
/>
</View>
)
};
const styles = {
container: {
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
},
image: {
flex: 1,
}
};
export {BackgroundImage};
that component will fill your container with any image you wish ;)
import React from 'react';
import { View, Image } from 'react-native';
class List extends Component {
render() {
let source = {uri: 'http://via.placeholder.com/350x150'};
return (
<View style = {{backgroundColor: 'black'}>
<BackgroundImage
resizeMode="cover"
opacity={0.6}
source={source}
/>
<View style={styles.content}>
<SVGImage
style={{ width: 80, height: 80 }}
source={{uri:'https://fluent-
panda.appspot.com.storage.googleapis.com/dumbbell.svg'}}/>
</View>
</View>
)
}
export default List;
Had a similar problem with adding text over map components and it was solved by adding z-index: -1 to the back element (in this case, the map)

Resources