Some changes in function and setState function? - reactjs

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;

Related

React Native Firebase state undefined

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>
)
}
}

Single textinput component to handle password validation, login and email validation

Question
Thanks to the props could I make a single textInput custom component to handle differents validations ?
Code
Down below you will find the main Login screen, it's really simple and it consists in 2 text inputs.
import React, { PureComponent, } from 'react';
import { View } from 'react-native';
import MkTextInput from '../../components/MkTextInput'
class LoginScreen extends PureComponent {
state = {
username: '',
password: '',
}
textChanged = fieldName => newValue => this.setState({ [fieldName]: newValue });
render() {
const { username } = this.state;
return(
<View>
<MkTextInput placeholderName='Username' usernameValidation value={username} onChangeText={this.textChanged('username')}/>
<MkTextInput placeholderName='Password' passwordValidation value={username} onChangeText={this.textChanged('password')} />
</View>
)
}
}
export default LoginScreen;
Down below here is the MkTextInputComponent
import React, { PureComponent, Fragment } from 'react';
import { Item, Input, Icon } from 'native-base';
import { userValidation, isTooShort } from '../utils/Validations/UserAndPassValidation';
import { passwordValidator } from '../utils/Validations/PasswordValidation';
import { styles } from './styles';
//ricorda di tradurre tutti i path in path assoluti -->leggi la documentazione.
class MkTextInput extends PureComponent {
state = {
data: '',
}
render() {
const { placeholderName,
usernameValidation,
passwordValidation,
emailValidation,
onChangeText,
value,
} = this.props;
const checkedUsername = usernameValidation ? userValidation(value) : false;
const checkedPassword = passwordValidation ? passwordValidator (value) : false;
return (
<Fragment>
<Item style={styles.container}>
<Input placeholder={placeholderName}
onChangeText={onChangeText}
secureTextEntry={checkedUsername? true : false}
style={checkedUsername ? styles.success : styles.failed}
/>
<Icon name={checkedUsername ? 'checkmark-circle' : 'close-circle'}/>
</Item>
</Fragment>
);
}
}
export default MkTextInput;
The plan
my first intention was to set a specified behaviour based on the props that the MkTextInput components will receive: If you have the props "passwordValidation" the component will deal the validation of the string with this line of code, and will ignore the remaining validation.
const checkedPassword = passwordValidation ? passwordValidator (value) : false;
unluckly this way brings me to has several re-rendering of the same component, or to change the style of the password field just only writing in the username field.
There is a way to make things works ?
unluckly this way brings me to has several re-rendering of the same component, or to change the style of the password field just only writing in the username field.
The above statement is a bit confusing. Are you trying to say that when you enter/type in username field your password field changes styles?
Oh and btw your below code has a mistake. I guess the value props of password field should be value={password} instead of value={username}
return(
<View>
<MkTextInput placeholderName='Username' usernameValidation value={username} onChangeText={this.textChanged('username')}/>
<MkTextInput placeholderName='Password' passwordValidation value={password} onChangeText={this.textChanged('password')} />
</View>
)
Maybe if you can give a little more description on what exactly you are stuck at or your code then maybe I would be able to help.
I think that after several tries i got an answer. Here is my solution:
Login component:
import React, { PureComponent, } from 'react';
import { View } from 'react-native';
import MkTextInput from '../../components/MkTextInput'
class LoginScreen extends PureComponent {
state = {
username: '',
password: '',
email: '',
}
textChanged = fieldName => newValue => this.setState({ [fieldName]: newValue });
render() {
const { username, password, email } = this.state;
return(
<View>
<MkTextInput placeholderName='Username' usernameValidation value={username} onChangeText={this.textChanged('username')} />
<MkTextInput placeholderName='Password' passwordValidation value={password} onChangeText={this.textChanged('password')} />
<MkTextInput placeholderName='E-mail' emailValidation value={email} onChangeText={this.textChanged('email')} />
</View>
)
}
}
export default LoginScreen;
And down below you will find the MkTextInput component
import React, { PureComponent } from 'react';
import { Item, Input, Icon } from 'native-base';
import { usernameValidator, passwordValidator, emailValidator } from '../utils/Validations';
import { styles } from './styles';
//ricorda di tradurre tutti i path relativi in path assoluti -->leggi la documentazione.
class MkTextInput extends PureComponent {
state = {
data: '',
}
render() {
const { placeholderName,
usernameValidation,
passwordValidation,
emailValidation,
onChangeText,
value,
} = this.props;
const checkedUsername = usernameValidator(value) ? <Icon name='checkmark-circle'/> : !value || (value !== null && <Icon name='close-circle'/>);
const checkedPassword = passwordValidator(value) ? <Icon name='checkmark-circle' /> : !value || (value !== null && <Icon name='close-circle'/>);
const checkedEmail = emailValidator(value) ? <Icon name='checkmark-circle' /> : !value || (value !== null && <Icon name='close-circle' />);
return (
<Item style={styles.inputContainer}>
<Input placeholder={placeholderName || ''}
onChangeText={onChangeText}
autoCapitalize='none'
secureTextEntry={passwordValidation ? true : false}
/>
{usernameValidation ? checkedUsername : null}
{passwordValidation ? checkedPassword : null}
{emailValidation ? checkedEmail : null}
</Item>
);
}
}
export default MkTextInput;

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;
...
}

Material-ui Textfield auto-scroll up the window on first redux-form/FOCUS

I made a form using redux-form with Textfield from material-ui to send an email. Everything is working well except a single thing : When I click on a TextField for the FIRST time, the window scroll uptop. Sometime, the focus stay on the TextField. Afterward it's working fine
Here's an example of what's happening Example
My form:
import React, { PropTypes, Component } from 'react';
import { reduxForm } from 'redux-form';
import TextField from 'material-ui/TextField';
import RaisedButton from 'material-ui/RaisedButton';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import styles from './EmailForm.css';
import theme from '../../../theme/theme';
import { mediaQueries } from '../../../decorators';
export const fields = ['name', 'email', 'subject', 'message'];
const validate = values => {
...
};
#mediaQueries
#withStyles(styles)
#reduxForm({
form: 'EmailForm',
fields,
validate
})
export default class EmailForm extends Component {
static propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired,
mediaQueries: PropTypes.func.isRequired,
};
state = {
mobile: false,
}
componentDidMount() {
this.props.mediaQueries('(max-width: 399px)', () => {
this.setState({ mobile: true });
});
this.props.mediaQueries('(min-width: 400px) and (max-width: 919px)', () => {
this.setState({ mobile: true });
});
this.props.mediaQueries('(min-width: 920px)', () => {
this.setState({ mobile: false });
});
}
render() {
const { fields: { name, email, subject, message }, handleSubmit, submitting } = this.props;
const emailMarginLeft = this.state.mobile ? 0 : '8px';
// SOME STYLE HERE
return (
<form
className={styles.form}
onSubmit={handleSubmit} >
<div className={styles.nameAndEmail}>
<TextField style={nameFieldStyle}
floatingLabelText="Votre Nom"
floatingLabelStyle={labelStyle}
floatingLabelFocusStyle={labelFocusStyle}
errorText={(name.touched && name.error) ? name.error : ''}
errorStyle={errorStyle}
id="nameField"
{...name} />
<TextField style={emailTextField}
floatingLabelText="Votre courriel"
floatingLabelStyle={labelStyle}
floatingLabelFocusStyle={labelFocusStyle}
errorText={(email.touched && email.error) ? email.error : ''}
errorStyle={errorStyle}
id="emailField"
{...email} />
</div>
<div className={styles.subjectAndMessage}>
<TextField style={textField}
floatingLabelText="Sujet"
floatingLabelStyle={labelStyle}
floatingLabelFocusStyle={labelFocusStyle}
errorText={(subject.touched && subject.error) ? subject.error : ''}
errorStyle={errorStyle}
id="sujet"
{...subject} />
<TextField style={messageTextField}
floatingLabelText="Message"
floatingLabelStyle={labelStyle}
floatingLabelFocusStyle={labelFocusStyle}
errorText={(message.touched && message.error) ? message.error : ''}
errorStyle={errorStyle}
multiLine
rows={5}
id="message"
{...message} />
</div>
<RaisedButton
style={buttonStyle}
key="submitButton"
type="submit"
label="Envoyer"
primary
disabled={submitting} />
</form>
);
}
}
The component using the form :
#withStyles(styles)
export default class ContactUs extends Component {
constructor(props) {
super(props);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(data) {
// Do stuff
}
render() {
return (
<div className={styles.contactUs}>
<h2>Formulaire</h2>
<EmailForm
ref="EmailForm"
onSubmit={this.handleSubmit}
submitting />
</div>
);
}
}
The theme imported contain the color used for material-ui style.
I have also found that onFocus and onBlur props of the TextFields doesn't work. I tried to simply log text and it doesn't work.
What makes it even weirder is that it isnt the first time I'm using this emailForm. I used it on another site and it was working perfectly fine.
Anyone has an idea of why it's happening?

Resources