I am learning react-native programming for android application. I am trying to start second screen on pressing on TouchableOpacity. I am using navigator for same.
I am getting this error undefined is not an object( evaluating this.props.navigator.push')
I have checked a lot of threads React Native, NavigatorIOS, undefined is not an object (evaluating 'this.props.navigator.push') undefined is not an object(evaluating this.props.navigator.push) but did not work for me. I am not sure what I am doing wrong here, can anyone help me . Thanks in advance.
index.android.js
/**
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import { AppRegistry, Text, View, TextInput, TouchableOpacity, ToolbarAndroid, StyleSheet,Container,ScrollView, Navigator } from 'react-native';
class App extends Component {
renderScene (route, navigator) {
return <route.component navigator={navigator} />
}
render() {
return (
<Navigator
style={styles.container}
renderScene={this.renderScene.bind(this)}
initialRoute={{component: LoginComponent}}
/>
);
}
}
class LoginComponent extends Component {
_navigate () {
this.props.navigator.push({
component: DashboardComponent
})
}
render() {
return (
<View style={{flex: 1, flexDirection: 'column'}}>
<ToolbarAndroid title='LOGIN' titleColor='white'
onIconClicked={() => this.props.navigator.pop()}
style={styles.toolbar}/>
<View style={{padding:10}}>
<TextInput style={{height: 40, borderColor:'gray', borderWidth: .5}}
placeholder="Email address" underlineColorAndroid='transparent'/>
<TextInput style={{height: 40, borderColor:'gray', borderWidth: .5}}
placeholder="Password" secureTextEntry={true} underlineColorAndroid='transparent'/>
<TouchableOpacity style={{ height: 40, marginTop: 10 , backgroundColor: '#2E8B57'}} onPress={this._navigate.bind(this)}>
<Text style={{color: 'white', textAlign: 'center', marginTop: 10, fontWeight: 'bold'}}>LOGIN</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
toolbar: {
backgroundColor: '#2E8B57',
height: 40,
fontFamily: 'noto_serif_regular',
},
});
AppRegistry.registerComponent('ExampleOne', () => LoginComponent);
second.android.js
import React, { Component } from 'react';
class DashboardComponent extends Component {
render() {
return (
<Text>Hello!</Text>
);
}
}
You register wrong component in AppRegistry.registerComponent, it should be App instead of LoginComponent
Navigator component need to be render first, then it will render and pass navigator prop down to it scenes.
Related
I'm making a simple chat application with React native and Firebase. But I could not manage to send the data I wanted to add to the database with the sendMessage function. I am getting an error like this and could not find the solution. Can you help me? I couldn't find where addDoc () belongs and also I don't know what SyntheticObject means. I am having such a problem, although I do not exactly comply with what was said in the tutorial video I followed the project.
Error image:
https://i.resmim.net/i/WhatsApp-Image-2021-05-25-at-21.34.11.jpeg
Error: Function addDoc() invalid data.
import React, {useLayoutEffect, useState} from 'react'
import { TouchableOpacity } from 'react-native';
import { StyleSheet, Text, View } from 'react-native'
import {Avatar} from "react-native-elements";
import {AntDesign, FontAwesome, Ionicons} from "#expo/vector-icons";
import { SafeAreaView } from 'react-native';
import { StatusBar } from 'expo-status-bar';
import { KeyboardAvoidingView, TextInput } from 'react-native';
import { Platform } from 'react-native';
import { ScrollView } from 'react-native';
import { Keyboard } from 'react-native';
import { TouchableWithoutFeedback } from 'react-native';
import { db, auth } from '../firebase';
import * as firebase from "firebase";
const ChatScreen = ({ navigation, route }) => {
const [input, setInput] = useState("");
useLayoutEffect(() => {
navigation.setOptions({
title: "Chat",
headerBackTitleVisible: false,
headerTitleAlign: "left",
headerTitle: () => (
<View
style={{
flexDirection: "row",
alignItems: "center",
}}>
<Avatar rounded source={{uri: "https://cencup.com/wp-content/uploads/2019/07/avatar-placeholder.png",}} />
<Text
style={{color: "white", marginLeft: 10, fontWeight: "700"}}
>{route.params.chatName}</Text>
</View>
),
headerLeft: () => (
<TouchableOpacity
style={{marginLeft: 10}}
onPress={navigation.goBack}
>
<AntDesign name="arrowleft" size={24} color="white" />
</TouchableOpacity>
),
headerRight: () => (
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
width: 80,
marginRight: 20,
}}>
<TouchableOpacity>
<FontAwesome name="video-camera" size={24} color="white" />
</TouchableOpacity>
<TouchableOpacity>
<Ionicons name="call" size={24} color="white" />
</TouchableOpacity>
</View>
)
});
}, [navigation]);
const sendMessage = () => {
Keyboard.dismiss();
db.collection('chats').doc(route.params.id).collection('messages').add({
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
message: input,
displayName: auth.currentUser.displayName,
email: auth.currentUser.email,
photoURL: auth.currentUser.photoURL
})
setInput('')
};
return (
<SafeAreaView style={{ flex: 1, backgroundColor: "white"}}>
<StatusBar style="light" />
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
keyboardVerticalOffset={90}>
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<>
<ScrollView>
</ScrollView>
<View style={styles.footer}>
<TextInput
placeholder="Signal Message"
value={input}
onChange={text => setInput(text)}
onSubmitEditing={sendMessage}
style={styles.textInput}/>
<TouchableOpacity onPress={sendMessage} activeOpacity={0.5}>
<Ionicons name="send" size={24} color="#2B68E6" />
</TouchableOpacity>
</View>
</>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
</SafeAreaView>
)
}
export default ChatScreen
const styles = StyleSheet.create({
container: {
flex:1,
},
footer: {
flexDirection: "row",
alignItems: "center",
width: "100%",
padding: 15,
},
textInput:{
bottom: 0,
height: 40,
flex: 1,
marginRight: 15,
backgroundColor: "#ECECEC",
padding: 10,
color: "grey",
borderRadius: 30,
},
})
Error image:
https://i.resmim.net/i/WhatsApp-Image-2021-05-25-at-21.34.11.jpeg
onChange={text => setInput(text)}
While you've called the parameter "text", it's actually an event object, specifically a "SyntheticEvent" (these are event objects used by react). So later when you try to send that to the database, firebase says, basically, "uh, i can't serialize this".
Instead, you may want to use the onChangeText event:
onChangeText={text => setInput(text)}
Your onChange function should be like this
onChange={e => setInput(e.nativeEvent.text)}
You're sending the event object not the text
You could also use onChangeText prop instead
onChangeText={text => setInput(text)}
I have following code in App.js
import React, { Component } from 'react';
import { Text, View,} from 'react-native';
import{DrawerNavigator, DrawerActions} from 'react-navigation';
import { Menu} from './src/components/menu';
export default class MainView extends Component {
render(){
return(
<View>
<Menu />
<Text> WHAT ??? </Text>
</View>
);
}
}
and following code in src/components/menu.js
'use strict';
import React, { Component } from 'react';
import { Text, View, StyleSheet, Image, ScrollView} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome5';
import{DrawerNavigator, DrawerActions} from 'react-navigation';
export class Menu extends Component {
render(){
return(
<View style= {styles.navContainer}>
<View style= {styles.navContainerFlexing}>
<View>
<Icon name="bars" size={25} color= 'black' style={{marginLeft: 10, fontWeight: '200' }} onPress={() => this.props.navigation.dispatch(DrawerActions.toggleDrawer())} />
</View>
<Text style={[styles.whiteText, styles.navItem]}>Home</Text>
</View>
</View>
);
}
}
export const Drawer = DrawerNavigator(
{
Menu: Menu,
},
{
// initialRouteName: 'Home',
},
{
drawerPosition: 'left',
initialRouteName: 'Home',
drawerBackgroundColor: 'white',
drawerWidth: 300,
}
);
const styles= StyleSheet.create({
navContainer: {
height: 55,
backgroundColor: '#3ba558',
alignItems: 'center',
// flex: 1,
flexDirection: 'row',
// justifyContent: 'flex-start'
},
navContainerFlexing: {
flex: 2,
flexDirection: 'row',
backgroundColor: '#3ba558',
paddingLeft: 20
},
whiteText: {
color: 'white',
},
navItem: {
alignItems: 'center',
marginTop: 'auto',
marginBottom: 'auto',
marginLeft: 10
},
});
Now I want my Menu class to display in App.js, which is displaying but and I also want it workable DrawerNavigator in homepage, right now the drawer is giving:
undefined is not an object (evaluating '_this.props.navigation.dispatch')
I Have explained the configuration of DrawerNavigator in the below link.
Look into the accepted answer in the below link.
How to create a Drawer Component and adding it to multiple screens
As I explained in it try to understand the concept and do not copy the syntax.
Do a comparison with your configuration, you will find your problem.
im just learning how to use react native but im having a little trouble when im trying to import an external component, i got an unexpected token (13:6) error. i jsut cant figure it out what im doing woring, please help me and show me what is wrong and why i cant import the component .
thank you
this is my code
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import ComponenteTexto from './componenteTexto';
export default class primero extends Component {
render() {
return (
<View style={styles.container}>
<componenteTexto/>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.android.js
</Text>
<Text style={styles.instructions}>
Double tap R on your keyboard to reload,{'\n'}
Shake or press menu button for dev menu,{'\n'}
<Text style={styles.instructions1}>
te amo tefita {5*2}
</Text>
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: 'skyblue',
marginBottom: 8,
},
instructions1: {
fontSize: 25,
textAlign: 'center',
color: 'black',
marginBottom: 8,
},
});
AppRegistry.registerComponent('primero', () => primero);
`
and this is the component i am trying to import
import React, {Component} from 'react';
import {
View,
Text
} from 'react-native';
export default class ComponenteTexto extends Component {
render() {
return{
<View>
<Text>
Prueba
</Text>
</View>
}
}
}
and this is what i get as error
enter image description here
Your ComponenteTexto component is using { } instead of ( ) in the return statement so it's not returning the expected type of object. Try changing it to:
return (
<View>
<Text>
Prueba
</Text>
</View>
)
I tried react-native on Button which is working fine. I want to customize Button so this made me to go for TouchableOpacity. I am trying to setup react native navigation like below which is not working now.
I am using this for navigation https://reactnavigation.org/
index.android.js
/**
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from "react";
import {
AppRegistry,
Image,
View,
Text,
Button,
StyleSheet,
TouchableOpacity
} from "react-native";
import { StackNavigator } from "react-navigation";
import EnableNotificationScreen from "./EnableNotificationScreen";
import styles from "./Styles";
import * as strings from "./Strings";
class SplashScreen extends Component {
render() {
console.disableYellowBox = true;
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Image source={require("./img/talk_people.png")} />
<Text style={styles.textStyle}> {strings.talk_people} </Text>
<TouchableOpacity>
<View
style={{
backgroundColor: "#FE434C",
alignItems: "center",
justifyContent: "center",
borderRadius: 10,
width: 240,
marginTop: 30,
height: 40
}}
onPress={() => {
this.navigate("EnableNotifcation");
}}
>
<Text style={{ color: "white" }}>CONTINUE</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const ScheduledApp = StackNavigator(
{
Splash: {
screen: SplashScreen,
navigationOptions: {
header: {
visible: false
}
}
},
EnableNotification: {
screen: EnableNotificationScreen,
navigationOptions: {
header: {
visible: false
}
}
}
},
{
initialRouteName: "Splash"
}
);
AppRegistry.registerComponent("Scheduled", () => ScheduledApp);
It was a tpyo error at this line this.navigate("EnableNotifcation");
I corrected it and it is working now. this.navigate("EnableNotification");
The onPress prop should be inside TouchableOpacity, not inside of the View props like you have it. See the pseudo code below
<TouchableOpacity onPress = {...}>
<View style = {{}}>
//Rest of the code
This should fix it. On a sidenote, i would recommend adding a new style for your view component, theres a lot of elements in there :P
Edit:
<TouchableOpacity onPress = {/*do this*/}>
<View style={{ backgroundColor: "#FE434C",
alignItems: "center",
justifyContent: "center",
borderRadius: 10,
width: 240, marginTop: 30,
height: 40 }}>
<Text style={{ color: "white" }}>
{"CONTINUE"}
</Text>
</View>
</TouchableOpacity>
Using following worked for me. using react native 0.62.2. See TouchableOpacity is inside KeyboardAvoidingView and ScrollView keyboardShouldPersistTaps.
<ScrollView keyboardShouldPersistTaps="handled">
<KeyboardAvoidingView enabled>
<View>
<TouchableOpacity
onPress={() => functionNameToNavigate('ScreenToMoveOn')}> <Text>Click me</text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ScrollView>
I have this screen in react native
import React, { Component } from 'react';
import { AppRegistry,TouchableOpacity, Text ,Button,Image,TextInput,PropTypes,StyleSheet,View,NavigatorIOS,TouchableHighlight} from 'react-native';
class LoginView extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>
HYGEX
</Text>
<View>
<TextInput
placeholder="Username"
style={styles.formInput}
/>
<TextInput
placeholder="Password"
secureTextEntry={true}
style={styles.formInput1}
/>
<TouchableHighlight style={styles.button}
onPress={() => this.move()}>
<Text style={styles.buttonText}>Login</Text>
</TouchableHighlight>
</View>
</View>
);
}
move() {
//what i can do here to go to Socrce screen ???
}
}
Something like login screen, now when I click into TouchableHighlight
I need to open this screen
'use strict';
import React, { Component } from 'react';
import { AppRegistry, ListView, Text, View } from 'react-native';
class HygexListView extends Component {
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'John', 'Joel', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
])
};
}
render() {
return (
<View style={{flex: 1, paddingTop: 22}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
</View>
);
}
}
module.exports = HygexListView;
I tried to implement move method but I failed! Any idea why?
Does react-native have a method to change the screen when click into TouchableHighlight?
As others pointed out, you have to use an instance of Navigator to transition between screens. Maybe you can have a look at the example apps in the React Native repo. I also find this router package quite easy to set up, and it also includes an example app that you can use as a starting point.
Edit
As a simple example using react-native-router-flux, you can edit the Example.js file in the Example directory to look like this:
import React, {
Component,
} from 'react';
import {
StyleSheet,
Text,
View,
} from 'react-native';
import LoginView from './LoginView';
import HygexListView from './HygexListView';
import {
Scene,
Router,
Actions,
} from 'react-native-router-flux';
const styles = StyleSheet.create({
container: { flex: 1, backgroundColor: 'transparent', justifyContent: 'center',
alignItems: 'center',
},
tabBarStyle: {
backgroundColor: '#eee',
},
tabBarSelectedItemStyle: {
backgroundColor: '#ddd',
},
});
// define this based on the styles/dimensions you use
const getSceneStyle = (/* NavigationSceneRendererProps */ props, computedProps) => {
const style = {
flex: 1,
backgroundColor: '#fff',
shadowColor: null,
shadowOffset: null,
shadowOpacity: null,
shadowRadius: null,
};
if (computedProps.isActive) {
style.marginTop = computedProps.hideNavBar ? 0 : 64;
style.marginBottom = computedProps.hideTabBar ? 0 : 50;
}
return style;
};
class Example extends Component {
render() {
return (
<Router getSceneStyle={getSceneStyle}>
<Scene key="login" component={LoginView} initial={true}/>
<Scene key="hygex" component={HygexListView } />
</Router>
);
}
}
export default Example;
Then, in your component's move function, you have to do the following:
move(){
Actions.hygex(); // This will perform a slide transition, but you can customize it. Have a look at the docs for that.
I have not tested the code, so there might be some typos/missing imports/code, but it should give you an idea of what you have to do.
}
You have to implement a Navigator, which is roughly a component that manages all stuff related to screens, and header bar with back button and etc.
As you are a beginner, I suggest you to look at the docs on this link:
https://facebook.github.io/react-native/docs/navigator.html
Sorry for the short answer, I'm on my phone.
Good luck!
"use strict";
var React = require("react-native");
var {
Component,
StyleSheet,
Text,
TextInput,
TouchableHighlight,
View,
} = React;
var SecureView = require("./SecureView");
class LoginView extends Component {
constructor(props) {
super(props);
this.state = {
username: "",
password: ""
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.title}>
Sign In
</Text>
<View>
<TextInput
placeholder="Username"
onChange={(event) => this.setState({username: event.nativeEvent.text})}
style={styles.formInput}
value={this.state.username} />
<TextInput
placeholder="Password"
secureTextEntry={true}
onChange={(event) => this.setState({password: event.nativeEvent.text})}
style={styles.formInput}
value={this.state.password} />
<TouchableHighlight onPress={(this.onSubmitPressed.bind(this))} style={styles.button}>
<Text style={styles.buttonText}>Submit</Text>
</TouchableHighlight>
</View>
</View>
);
}
onSubmitPressed() {
this.props.navigator.push({
title: "Secure Page",
component: SecureView,
passProps: {username: this.state.username, password: this.state.password},
});
}
};
var styles = StyleSheet.create({
container: {
padding: 30,
marginTop: 65,
alignItems: "stretch"
},
title: {
fontSize: 18,
marginBottom: 10
},
formInput: {
height: 36,
padding: 10,
marginRight: 5,
marginBottom: 5,
marginTop: 5,
flex: 1,
fontSize: 18,
borderWidth: 1,
borderColor: "#555555",
borderRadius: 8,
color: "#555555"
},
button: {
height: 36,
flex: 1,
backgroundColor: "#555555",
borderColor: "#555555",
borderWidth: 1,
borderRadius: 8,
marginTop: 10,
justifyContent: "center"
},
buttonText: {
fontSize: 18,
color: "#ffffff",
alignSelf: "center"
},
});
module.exports = LoginView;
You have to use navigator. please read the documentation as mentioned below. and if you will need then i will share you my code.
Here is an example: NavigatorExample