React Native Firebase state undefined - reactjs

I've tried multiple implementations, and I can't seem to get the state to not be undefined. I've tried arrow functions, I've tried binding this inside the onChange event, and nothing seems to work. Can somebody take my codebase and give me some insight as to what I'm doing wrong? Thanks!
import React from 'react';
import {View, Image, StyleSheet} from 'react-native';
import {Button, Text, Input} from 'react-native-elements';
import Icon from 'react-native-vector-icons/FontAwesome';
const styles = StyleSheet.create({
heading: {
padding: 20,
},
});
export default class ContactForm extends React.Component
{
constructor(props)
{
super(props);
this.state = {
name: '',
email: '',
}
}
handleName(e)
{
this.setState({name: e.target.value})
console.log(e.target.value);
}
handleEmail(e)
{
}
submit(e)
{
console.log(this.state.name + " " + this.state.email);
}
render()
{
return (
<View style={styles.heading}>
<Text h5>Sign up to receive updates/newsletters!</Text>
<Input placeholder="your name" onChange={this.handleName.bind(this)} />
<Input placeholder="your email" onChange={this.handleEmail.bind(this)} />
<Button title="Submit" onPress={this.submit}/>
</View>
)
}
}

Hi you can do it like this there is no need to bind the arrow function with "this".
export default class ContactForm extends React.Component
{
constructor(props)
{
super(props);
this.state = {
name: '',
email: '',
}
}
handleName=(e)=>
{ console.log(e);
this.setState({name: e})
}
handleEmail=(e)=>
{
this.setState({email: e})
}
submit=()=>
{
console.log(this.state.name + " " + this.state.email);
}
render()
{
return (
<View style={styles.heading}>
<Text h5>Sign up to receive updates/newsletters!</Text>
<Input placeholder="your name" onChangeText ={this.handleName} />
//change onChange to onChangeText
<Input placeholder="your email" onChangeText={this.handleEmail} />
<Button title="Submit" onPress={this.submit}/>
</View>
)
}
}

Related

Why value of input here at reactjs is undefined?

I want to change state by the value of input but it is undefined.
It should work, the value is for every HTML tag so what is wrong with my code??
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
this.handleChange = this.handleChange(this);
}
handleChange(event) {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
/>
<h1>{this.state.value}</h1>
</form>
);
}
}
export default App;
There's no value stored in your state, so it is undefined, and you do not correctly bind this to your handler. Output this.state.firstName instead:
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
/>
<h1>{this.state.firstName}</h1>
</form>
);
}
}
export default App;
First try to bind this for handleChange using an arrow function. Also use the state variable to set the value property of the input .
Sandbox link: https://codesandbox.io/s/react-basic-example-qmyw5
import React, { Component } from "react";
class App extends Component {
constructor() {
super();
this.state = {
firstName: " "
};
}
handleChange = (event) => {
this.setState({
firstName: event.target.value
});
}
render() {
return (
<form>
<input
type="text"
placeholder="Firstname"
onChange={this.handleChange}
value={this.state.firstName}
/>
<h1>{this.state.firstName}</h1>
</form>
);
}
}
export default App;

Keep getting an error "undefined is not an object (evaluating '_this.refs.name.value')"

I'm doing the ReactNative mobile app. WebApp runs smoothly and everything works. But when I transfer everything to the mobile part, I'm stuck with an error when I enter the text in input field. What I'm doing wrong and what is my mistake? Here is my code:
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App extends React.Component {
state={
message:"Hi {name}, your rating for this app is {rating}"
}
handleName=()=>{
this.setState({
message:"Hi "+this.refs.name.value+", your rating for this app is {rating}"
})
}
handleRating=()=>{
this.setState({
message:"Hi "+this.refs.name.value+", your rating for this app is "+this.refs.rating.value
})
}
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Your Name"
ref="name"
onChangeText={this.handleName}
/>
<TextInput
placeholder="Your Rating"
ref="rating"
onChangeText={this.handleRating}
/>
<View>{this.state.message}</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
I don't think that referring to the TextInput component like that (using a string reference) is the best way to achieve this. However, if you want to, you could use this.refs.name._lastNativeText to access the current value of the TextInput instead of this.refs.name.value.
In my opinion, a better way would be to use the value returned by onChangeText() callback. You could do that like this:
import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
name: null,
rating: null,
message: null,
}
}
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Your Name"
onChangeText={text => this.setState({name: text})}
/>
<TextInput
placeholder="Your Rating"
onChangeText={text => this.setState({rating: text})}
/>
{ this.state.name && this.state.rating &&
<Text>Hi {this.state.name}, your rating for this app is {this.state.rating}.</Text>
}
</View>
);
}
}
I haven't tested this code, comment below if you face some error.

Some changes in function and setState function?

I am doing such things in reactjs but when I started learning react-native it is not working can you tell me how to perform such tasks??
import React, {Component} from 'react';
import {Text, View, Form } from 'react-native';
import { FormLabel, FormInput, FormValidationMessage, Button } from 'react-native-elements';
class Header extends Component {
constructor(props){
super(props);
this.state = {
email : '',
password : '',
};
}
inputData = event => {
this.setState({
[event.target.name]:event.target.value
});
}
submitData = event => {
event.preventDefault();
console.log(this.state);
}
render(){
return(
<View>
<Text style= {{fontSize : 40, marginTop : 50, marginLeft : 100, fontWeight : 'bold'}}>
New App!
</Text>
<FormLabel>Email</FormLabel>
<FormInput name='email' type='email' onChange={this.inputData}/>
<FormLabel>Password</FormLabel>
<FormInput name='password' type='password' onChange={this.inputData}/>
<Button title='Submit' onPress={this.submitData} style={{marginTop:20}}/>
</View>
);
}
}
export default Header;
As you can see over here is that when I used onChange the values are not getting assigned.
I know how to use with onChangeText and it's working also, but can you tell me why the above approach is not working and if not then any significant reasons???
You can try this way, use onChangeText instead of onChange
import React, {Component} from 'react';
import {Text, View, Form } from 'react-native';
import { FormLabel, FormInput, FormValidationMessage, Button } from 'react-native-elements';
class Header extends Component {
constructor(props){
super(props);
this.state = {
email : '',
password : '',
};
}
inputData = event => {
this.setState({
[event.target.name]:event.target.value
});
}
inputEmail = text => {
this.setState({
email: text
})
}
inputPassword = text => {
this.setState({
password: text
})
}
submitData = event => {
event.preventDefault();
console.log(this.state);
}
render(){
return(
<View>
<Text style= {{fontSize : 40, marginTop : 50, marginLeft : 100, fontWeight : 'bold'}}>
New App!
</Text>
<FormLabel>Email</FormLabel>
<FormInput value={this.state.email} name='email' type='email' onChangeText={this.inputEmail}/>
<FormLabel>Password</FormLabel>
<FormInput value={this.state.password} name='password' type='password' onChangeText={this.inputPassword}/>
<Button title='Submit' onPress={this.submitData} style={{marginTop:20}}/>
</View>
);
}
}
export default Header;

React Native - How to pass from screen to another screen?

I have an simple application that have just two screens: Login and Home. I want to go to Home screen from Login screen. I don't want to use a Navigator, if it is possible. This is my code:
Index.js
import { AppRegistry } from 'react-native';
import App from './src/App';
AppRegistry.registerComponent('App', () => App);
App.js
class App extends Component {
constructor(props) {
super(props);
}
render() {
return(
<LoginPage />
);
}
}
export default App;
LoginPage.js
export class LoginPage extends Component{
constructor(props) {
super(props);
this.state = { email: '', password: '' };
}
goToHomePage = () => {
// HERE!!!!!!
};
onButtonPress = () => {
this.goToHomePage();
};
render(){
return(
<View>
<TextInput
style={Styles.textInput}
onChangeText={(email) => this.setState({email})}
placeholder={'Email'}
value={this.state.email}
/>
<TextInput
style={Styles.textInput}
onChangeText={(password) => this.setState({password})}
secureTextEntry
placeholder={'Password'}
value={this.state.password}
/>
<Button onPress={() => this.props.navigation.navigate('HomePage')}
title="Login"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
};
}
HomePage.js
export class HomePage extends Component{
constructor(props) {
super(props);
}
goToLoginPage = () => {
// HERE !!!!!!
};
onButtonPress = () => {
this.goToLoginPage();
};
render () {
return (
<View style={Styles.container}>
<View>
<LoginHeader Title={'Titulo do HomePage'} />
</View>
<Button
style={Styles.button}
title={'Logout'}
onPress={this.onButtonPress}
/>
</View>
)
}
}
So, how can I implement a method for move to screens with this code? I've tried to use react-native-navigation and react-navigation, but does not work for me in this case.
EDIT
I've tried to use this:
App.js
import { createStackNavigator } from 'react-navigation';
const RootStack = createStackNavigator(
{
HomePage: HomePage,
LoginPage: LoginPage,
},
{
initialRouteName: 'LoginPage',
}
);
class App extends Component {
constructor(props) {
super(props);
}
render() {
return(
<RootStack />
);
}
}
export default App;
LoginPage.js
import { createStackNavigator } from 'react-navigation';
export class LoginPage extends Component{
constructor(props) {
super(props);
this.state = { email: '', password: '' };
}
goToHomePage = () => {
// HERE!!!!!!
};
onButtonPress = () => {
this.goToHomePage();
};
render(){
return(
<View>
<TextInput
style={Styles.textInput}
onChangeText={(email) => this.setState({email})}
placeholder={'Email'}
value={this.state.email}
/>
<TextInput
style={Styles.textInput}
onChangeText={(password) => this.setState({password})}
secureTextEntry
placeholder={'Password'}
value={this.state.password}
/>
<Button onPress={() => this.props.navigation.navigate('HomePage')}
title="Login"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
</View>
);
};
}
Do you import React, {Component} from "react"?

cannot destruct the style object

I'm trying to deconstruct the style object but it gives me error on the line const { errorTextStyle } = myStyle; saying: Unexpected token (8:8)".
Below is the whole code:
import React, { Component } from 'react';
import { Platform, Dimensions, Text } from 'react-native';
import { Card, CardSection, Button, Input } from './common';
class LoginForm extends Component {
/////////////////////
state = {email: '', password: '', error: ''};
const { errorTextStyle } = myStyle;
///////////////////// methods
onButtonPress(){
const { email, password } = this.state;
firebase.auth().signInWithEmailAndPassword(email,password).
catch(() => {
firebase.auth().createUserWithEmailAndPassword(email,password).
catch(() => {
this.setState({error: 'Authentication Failed.'});
});
});
}
////////////////////// render
render(){
return(
<Card>
<CardSection >
<Input
placeholder="Type here :)"
onChangeText={ email => this.setState({ email }) }
value={ this.state.email }
label={ 'Email: ' }
autoCorrect={false}
/>
</CardSection >
<CardSection >
<Input
placeholder="Type here :)"
onChangeText={ password => this.setState({password}) }
value={this.state.password}
label={'Password: '}
autoCorrect={false}
secureTextEntry
/>
</CardSection >
<Text style={ errorTextStyle }>
{this.state.error}
</Text>
<CardSection>
<Button onPress={this.onButtonPress.bind(this)}>
Login :)
</Button>
</CardSection>
</Card>
);
}
}
const myStyle = {
errorTextStyle: {
fontSize: 20,
alignSelf: 'center',
color: 'red'
}
};
export default LoginForm;
Since the variable is being used inside render, move that code inside that method. You can only declare methods and fields inside the class declaration, expressions must go inside a method. state = ... is working for you because that's a field declaration. Try the following:
render(){
const { errorTextStyle } = myStyle;
...
}

Resources