onChange doesn't work with mobile? - React Native - javascript

Right now I am trying to make a Log In Page and I've been using React Native to do so. It works perfectly fine on a web browser but when I try it on my phone, onChange doesn't seem to change the state of the password and username.
import React from 'react';
import { TextInput, View, TouchableOpacity, Text } from 'react-native';
class LogIn extends React.Component {
constructor(props){
super(props);
this.state={
username: 'John Doe',
password: 'abc123'
}
}
loginChangeHandler = (event) =>{
this.setState({[event.target.name]: event.target.value});
}
loginButtonHandler = () =>{
alert('username: '+this.state.username+ ' Password: '+this.state.password)
}
render() {
return (
<View style = {{alignItems: 'center'}}>
<TextInput name = 'username' onChange = {this.loginChangeHandler}
placeholder = 'username'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TextInput name = 'password' onChange = {this.loginChangeHandler} secureTextEntry={true}
placeholder = 'password'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TouchableOpacity onPress = {this.loginButtonHandler} style = {{height: 45, width: 200, justifyContent: 'center', alignItems: "center", backgroundColor: 'green'}}>
<Text style = {{fontSize: 16, color: 'white'}}>LOG IN</Text>
</TouchableOpacity>
</View>
);
}
}
export default LogIn;

To use this inside of a function you must bind the function with this object. Other thing is there isn't direct name prop for TextInput component and event.target is not returning something you expected. onChange is called with { nativeEvent: { eventCount, target, text} }, then i suggest you to use onChangeText callback. This callback is called with only the value which you are typing.
Change your code this way.
render() {
return (
<View style = {{alignItems: 'center'}}>
<TextInput name = 'username' onChangeText= {(value) => this.setState({ username : value })}
placeholder = 'username'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TextInput name = 'password' onChangeText={(value) => this.setState({ password : value })} secureTextEntry={true}
placeholder = 'password'
style={{ width: 200, height: 55, borderColor: 'gray', borderWidth: 1 }}
/>
<Text>{'\n'}</Text>
<TouchableOpacity onPress = {this.loginButtonHandler.bind(this)} style = {{height: 45, width: 200, justifyContent: 'center', alignItems: "center", backgroundColor: 'green'}}>
<Text style = {{fontSize: 16, color: 'white'}}>LOG IN</Text>
</TouchableOpacity>
</View>
);
}

Related

how to make empty useState of setSelectedCountry when props.cityName is changed in react native

How to make empty input field when props.cityname is changed in react native. setSelectedCountry is holding the selected city name and I want to make it empty when props.cityname value change
import React, {useRef, useState} from 'react';
import {
FlatList,
Image,
Text,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
const Test = props => {
const [search, setSearch] = useState('');
const [clicked, setClicked] = useState(false);
const [data, setData] = useState(props.cityNames);
const [selectedCountry, setSelectedCountry] = useState('');
const searchRef = useRef();
const onSearch = search => {
if (search !== '') {
const tempData = data.filter(item => {
return item.value.toLowerCase().indexOf(search.toLowerCase()) > -1;
});
setData(tempData);
} else {
setData(props.cityNames);
}
};
const isFound = data.some(element => {
if (element.value === selectedCountry) {
return true;
}
return false;
});
// React.useEffect(() => {
// setSelectedCountry('');
// }, [isFound]);
return (
<View>
<TouchableOpacity
style={{
paddingHorizontal: 16,
paddingVertical: 20,
borderRadius: 10,
backgroundColor: '#F2F4F7',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
onPress={() => {
setClicked(!clicked);
}}>
<Text style={{fontWeight: '600'}}>
{selectedCountry == '' ? 'Select Country' : selectedCountry}
</Text>
{clicked ? (
<Image
source={require('./upload.png')}
style={{width: 20, height: 20}}
/>
) : (
<Image
source={require('./dropdown.png')}
style={{width: 20, height: 20}}
/>
)}
</TouchableOpacity>
{clicked ? (
<View
style={{
marginTop: 10,
backgroundColor: '#F2F4F7',
borderRadius: 10,
paddingHorizontal: 0,
paddingVertical: 0,
borderColor: '#F2F4F7',
maxHeight: 300,
}}>
<TextInput
placeholder="Search.."
value={search}
ref={searchRef}
onChangeText={txt => {
onSearch(txt);
setSearch(txt);
}}
style={{
width: '90%',
alignSelf: 'center',
borderWidth: 1,
borderColor: 'white',
borderRadius: 10,
marginTop: 20,
paddingLeft: 16,
}}
/>
<FlatList
nestedScrollEnabled
data={data}
renderItem={({item, index}) => {
return (
<TouchableOpacity
style={{
width: '85%',
alignSelf: 'center',
paddingVertical: 16,
justifyContent: 'center',
}}
onPress={() => {
setSelectedCountry(item.value);
setClicked(!clicked);
onSearch('');
setSearch('');
}}>
<Text style={{fontWeight: '600'}}>{item.value}</Text>
</TouchableOpacity>
);
}}
/>
</View>
) : null}
</View>
);
};
export default Test;
**I want to add max-height so that the dropdown does not go down **
If I removed max-height then it will solve the issues but the length of the dropdown field is large so I need nice solutions
Can you check this snack
just make a little tweaks for ur code
https://snack.expo.dev/#sharqiyem/custom-dropdown
It's scrollable.

render-error-text-strings-must-be-rendered-within-a-text-component

Problem: I am displaying all the BOOKS imgs using Flatlist that is stored in a google URL. I am using expo. When I open the application in a browser with expo it works. But when I run it on my phone it shows me an error as given below.
Error: Render Error : Text strings must be rendered within a Component
here is the code:
import React, { Component } from 'react';
import {
Text,
View,
Image,
TextInput,
FlatList,
SectionList,
StyleSheet,
Button,
} from 'react-native';
class App extends React.Component {
constructor() {
super();
this.state = {
bookName: 'javascript',
};
}
componentDidMount() {
this.fetchApi();
}
fetchApi = async () => {
let apiKey = 'AIzaSyDxoyfayTuP-hFon-b-nuzGjPdDAbpIPCY';
const response = await fetch('https://www.googleapis.com/books/v1/volumes?q=' + this.state.bookName + '&key=' + apiKey + '&maxResults=5');
const json = await response.json();
this.setState({ data: json.items });
};
render() {
return (
<View style={styles.container}>
<Text
style={{
fontFamily: 'Arial',
fontSize: 20,
fontWeight: 'bold',
fontStyle: 'underline',
color: 'yellow',
marginTop: -300,
}}>
<Text>Random Users Data</Text>
</Text>
<View
style={{
width: 210,
height: 50,
marginTop: 50,
justifyContent: 'center',
}}>
<TextInput
style={{
width: 210,
height: 45,
fontSize: 18,
borderWidth: 3,
borderRadius: 12,
borderColor: 'royalblue',
textAlign: 'center',
backgroundColor: 'white',
}}
placeholder="Enter book name"
onChangeText={(item) => this.setState.bookName(item)}
/>{' '}
</View>
<View>
<FlatList
data={this.state.data}
keyExtractor={(x, i) => i}
renderItem={({ item }) => (
<View>
<View style={{ marginTop: 200 }}>
<Image
style={{ width: 128, height: 204, margin: 10 }}
source={{ uri: item.volumeInfo.imageLinks.thumbnail }}
/>
</View>
</View>
)}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
});
export default App;
Remove the {' '}. You probably accidentally added it while working on your project, but React is interpreting it as a space and complaining that text is found outside of a text component.

Can't get user data after logging in Firebase React Native Expo

I am trying to create a social media app with React Native / Expo and Firebase, and I have successfully been able to create accounts and login, but I am still trying to figure out how to get user data such as username when the user logs in. Basically, when I log in or create an account, I want the profile page to show the username and profile picture associated with the user that logged in, but I'm not sure how to do that. It probably has something to do with the AuthStateChanged() function or something like that, but I'm not sure.
Here is my App.js file:
import 'react-native-gesture-handler';
import React, { useState } from 'react';
import { LogBox, Text, View } from 'react-native';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import Feather from '#expo/vector-icons/Feather'
import { useFonts, Nunito_400Regular as NunitoRegular, Nunito_700Bold as NunitoBold } from '#expo-google-fonts/nunito';
import { NavigationContainer, DefaultTheme } from '#react-navigation/native';
import Navigator from './src/navigation/index';
import * as firebase from "firebase";
import "firebase/auth";
// Your web app's Firebase configuration
var firebaseConfig = {
apiKey: "AIzaSyB1TxcRpLQq0Zqs0f0FvPitIto0tZo_0xM",
authDomain: "shutter-42e70.firebaseapp.com",
projectId: "shutter-42e70",
storageBucket: "shutter-42e70.appspot.com",
messagingSenderId: "149059508529",
appId: "1:149059508529:web:0dbc5bbbb75bf022ef7810"
};
if (firebase.apps.length === 0) {
firebase.initializeApp(firebaseConfig);
}
// The theme we'll be using for our navigator
const MyTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
background: '#FAFAFA'
},
};
// Loads the Feather icons (https://docs.expo.io/guides/icons/)
function cacheFonts(fonts) {
return fonts.map(font => Font.loadAsync(font));
}
export default function App() {
const [assetsReady, setAssetsReady] = useState(false);
async function _loadFonts() {
const iconFontAssets = cacheFonts([Feather.font])
await Promise.all([...iconFontAssets]);
}
// Loads the Nunito font (https://docs.expo.io/guides/using-custom-fonts/)
let [fontsLoaded] = useFonts({
NunitoRegular, NunitoBold
});
// If the fonts or assets are not loaded, we show a default App Loading screen.
// Otherwise, we return our Photo Sharing App!
if (!fontsLoaded || !assetsReady) {
return <AppLoading
startAsync={_loadFonts}
onFinish={() => setAssetsReady(true)}
onError={console.warn}
/>
}
return (
<NavigationContainer theme={MyTheme}>
<Navigator />
</NavigationContainer>
);
}
Here is my Login.js file:
import React from 'react';
import { StyleSheet, View, Text, Image, TextInput, TouchableOpacity } from 'react-native';
import theme from '../../assets/themes';
import { Formik } from 'formik';
import { Octicons, Fontisto } from '#expo/vector-icons';
import Separator from './Separator';
import KeyBoardAvoidingWrapper from './KeyboardAvoidingWrapper';
import firebase from 'firebase';
var errorMsg = '...'
const Login = ({navigation}) => {
return (
<KeyBoardAvoidingWrapper>
<View>
<View style = {styles.StyledContainer}>
<View style = {styles.InnerContainer}>
<Image style = {styles.PageLogo} resizeMode = "cover" source = {require('./../../assets/images/logo.png')} />
<Text style = {styles.PageTitle}>Shutter</Text>
<Text style = {styles.TagLine}>Social Media for Photographers</Text>
</View>
</View>
<Formik
initialValues = {{email: '', password: ''}}
onSubmit = {(values) => {
firebase.auth().signInWithEmailAndPassword(values.email, values.password)
.then((result) => {
navigation.navigate('Feed');
})
.catch((error) => {
alert(error)
})
}}
>
{({handleChange, handleBlur, handleSubmit, values}) => (
<View style = {styles.styledFormArea}>
<MyTextInput
label = " "
icon = "mail"
placeholder = "email#email.com"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('email')}
onBlur = {handleBlur('email')}
value = {values.email}
keyboardType = "email-address"
/>
<MyTextInput
label = " "
icon = "lock"
placeholder = "password"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('password')}
onBlur = {handleBlur('password')}
value = {values.password}
secureTextEntry = {true}
/>
<Text style = {styles.msgBox}>{errorMsg}</Text>
<TouchableOpacity onPress = {handleSubmit} style = {styles.loginButton}>
<Text style = {styles.loginButtonText}>Login</Text>
</TouchableOpacity>
<Separator />
<TouchableOpacity onPress = {handleSubmit} style = {styles.googleSigninButton}>
<Fontisto name = "google" color = {theme.colors.white} size = {25} ></Fontisto>
<Text style = {styles.googleSigninButtonText}>Sign in with Google</Text>
</TouchableOpacity>
<View style = {styles.signupLinkView}>
<Text style = {styles.signupText}>Don't have an account? </Text>
<TouchableOpacity style = {styles.signupLinkButton}>
<Text onPress = {() => navigation.navigate('Sign Up')} style = {styles.signupLinkText}>Sign up</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
</View>
</KeyBoardAvoidingWrapper>
);
};
const MyTextInput = ({label, icon, ...props}) => {
return (
<View>
<View style = {styles.leftIcon}>
<Octicons name = {icon} size = {30} color = {theme.colors.primary} />
</View>
<Text style = {styles.styledTextInput}>{label}</Text>
<TextInput style = {styles.textInput} {...props} />
</View>
)
}
const styles = StyleSheet.create({
StyledContainer: {
flex: 1,
padding: theme.spacing.m,
paddingTop: theme.spacing.l,
backgroundColor: theme.colors.white,
marginTop: 80,
},
InnerContainer: {
justifyContent: 'center',
alignItems: 'center',
},
PageLogo: {
width: 100,
height: 100,
},
PageTitle: {
...theme.textVariants.h1,
marginTop: theme.spacing.m,
},
TagLine: {
...theme.textVariants.body3,
},
styledFormArea: {
justifyContent: 'center',
marginHorizontal: theme.spacing.l,
borderRadius: theme.borderRadius.m,
marginTop: 40,
},
leftIcon: {
position: 'absolute',
zIndex: 1,
marginTop: 28,
marginLeft: 12,
},
styledTextInput: {
...theme.textVariants.body3,
},
textInput: {
backgroundColor: theme.colors.gray,
paddingVertical: 10,
paddingLeft: 50,
paddingRight: theme.spacing.l,
borderRadius: theme.borderRadius.m,
},
loginButton: {
backgroundColor: theme.colors.primary,
alignItems: 'center',
marginTop: 20,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
},
loginButtonText: {
...theme.textVariants.body2,
color: theme.colors.white,
},
msgBox: {
...theme.textVariants.body3,
alignSelf: 'center',
},
googleSigninButton: {
backgroundColor: theme.colors.primary,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginTop: 16,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
},
googleSigninButtonText: {
...theme.textVariants.body2,
color: theme.colors.white,
paddingLeft: 25,
},
signupLinkView: {
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
padding: theme.spacing.sm,
},
signupText: {
...theme.textVariants.body3,
},
signupLinkButton: {
},
signupLinkText: {
...theme.textVariants.body3,
opacity: 0.6,
},
})
export default Login;
Here is my Signup.js file:
import React from 'react';
import { StyleSheet, View, Text, Image, TextInput, TouchableOpacity } from 'react-native';
import theme from '../../assets/themes';
import { Formik } from 'formik';
import { Octicons } from '#expo/vector-icons';
import Separator from './Separator';
import KeyboardAvoidingWrapper from './KeyboardAvoidingWrapper';
import firebase from 'firebase';
var errorMsg = '...'
const SignUp = ({navigation}) => {
return (
<KeyboardAvoidingWrapper>
<View>
<View style = {styles.StyledContainer}>
<View style = {styles.InnerContainer}>
<Image style = {styles.PageLogo} resizeMode = "cover" source = {require('./../../assets/images/logo.png')} />
<Text style = {styles.PageTitle}>Shutter</Text>
<Text style = {styles.TagLine}>Social Media for Photographers</Text>
</View>
</View>
<Formik
initialValues = {{fullName: '', email: '', username: '', password: '', confirmPassword: ''}}
onSubmit = {(values) => {
firebase.auth().createUserWithEmailAndPassword(values.email, values.password)
.then((result) => {
firebase.firestore().collection("users")
.doc(firebase.auth().currentUser.uid)
.set({
fullName: values.fullName,
displayName: values.email,
username: values.username,
password: values.password,
})
if (values.password === values.confirmPassword)
navigation.navigate('Signup Options')
else
errorMsg = 'Passwords do not match'
})
.catch((error) => {
alert(error)
})
}}
>
{({handleChange, handleBlur, handleSubmit, values}) => (
<View style = {styles.styledFormArea}>
<MyTextInput
label = "Name"
icon = "person"
placeholder = "John Doe"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('fullName')}
onBlur = {handleBlur('fullName')}
value = {values.fullName}
/>
<MyTextInput
label = "Email"
icon = "mail"
placeholder = "email#email.com"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('email')}
onBlur = {handleBlur('email')}
value = {values.email}
keyboardType = "email-address"
/>
<MyTextInput
label = "Username"
icon = "person"
placeholder = "username"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('username')}
onBlur = {handleBlur('username')}
value = {values.username}
/>
<MyTextInput
label = "Password"
icon = "lock"
placeholder = "password"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('password')}
onBlur = {handleBlur('password')}
value = {values.password}
secureTextEntry = {true}
/>
<MyTextInput
label = "Confirm Password"
icon = "lock"
placeholder = "retype password"
placeholderTextColor = {theme.colors.black}
onChangeText = {handleChange('confirmPassword')}
onBlur = {handleBlur('confirmPassword')}
value = {values.confirmPassword}
secureTextEntry = {true}
/>
<Text style = {styles.msgBox}>{errorMsg}</Text>
<TouchableOpacity onPress = {handleSubmit} style = {styles.loginButton}>
<Text style = {styles.loginButtonText}>Sign Up</Text>
</TouchableOpacity>
<Separator />
<View style = {styles.signupLinkView}>
<Text style = {styles.signupText}>Already have an account? </Text>
<TouchableOpacity style = {styles.signupLinkButton}>
<Text onPress = {() => navigation.navigate('Login')} style = {styles.signupLinkText}>Login</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
</View>
</KeyboardAvoidingWrapper>
);
};
const onSignUp = ({values}) => {
console.log(values);
}
const MyTextInput = ({label, icon, ...props}) => {
return (
<View style = {styles.inputFieldView}>
<View style = {styles.leftIcon}>
<Octicons name = {icon} size = {30} color = {theme.colors.primary} />
</View>
<Text style = {styles.styledTextInput}>{label}</Text>
<TextInput style = {styles.textInput} {...props} />
</View>
)
}
const styles = StyleSheet.create({
StyledContainer: {
flex: 1,
padding: theme.spacing.m,
paddingTop: theme.spacing.l,
backgroundColor: theme.colors.white,
marginTop: 80,
},
InnerContainer: {
justifyContent: 'center',
alignItems: 'center',
},
PageLogo: {
width: 100,
height: 100,
},
PageTitle: {
...theme.textVariants.h1,
marginTop: theme.spacing.m,
},
TagLine: {
...theme.textVariants.body3,
},
inputFieldView: {
marginTop: 12,
},
styledFormArea: {
justifyContent: 'center',
marginHorizontal: theme.spacing.l,
borderRadius: theme.borderRadius.m,
marginTop: 40,
},
leftIcon: {
position: 'absolute',
zIndex: 1,
marginTop: 28,
marginLeft: 12,
},
styledTextInput: {
...theme.textVariants.body3,
},
textInput: {
backgroundColor: theme.colors.gray,
paddingVertical: 10,
paddingLeft: 50,
paddingRight: theme.spacing.l,
borderRadius: theme.borderRadius.m,
},
loginButton: {
backgroundColor: theme.colors.primary,
alignItems: 'center',
marginTop: 20,
paddingVertical: 8,
borderRadius: theme.borderRadius.m,
},
loginButtonText: {
...theme.textVariants.body2,
color: theme.colors.white,
},
msgBox: {
...theme.textVariants.body3,
alignSelf: 'center',
},
signupLinkView: {
justifyContent: 'center',
flexDirection: 'row',
alignItems: 'center',
padding: theme.spacing.sm,
},
signupText: {
...theme.textVariants.body3,
},
signupLinkButton: {
},
signupLinkText: {
...theme.textVariants.body3,
opacity: 0.6,
},
})
export default SignUp;
Sorry if my code isn't written very well and isn't very organized. I couldn't find very many good tutorials on firebase authentication so this is what I came up with after watching like 5 different firebase authentication tutorials lol. Any help would be greatly appreciated!
Also, here is the link to my github repo if you want to see my entire project file: github repo
You should use redux or React hooks to save user info into global state.
https://reactjs.org/docs/hooks-reference.html#usecontext
https://redux.js.org/introduction/getting-started
In the callback of signInWithEmailAndPassword() return user profile data
firebase.auth().signInWithEmailAndPassword(email, password)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
/* user:
- email
- uid
- displayName
- emailVerified
- phoneNumber
- photoURL
- metadata
...
*/
})
.catch((error) => {
// catch error
});
Then in your components/screens, you can call the state to show user's data.

Arguments inside "onChange" its no compatble with "NativeSyntheticEvent<TextInputChangeEventData>"

I am new with react native and when i try do this
<TextInput
style={styles.input}
onChange={(text) => setPontoValue(text)}
/>
i receive this error
TS2345: Argument of type 'NativeSyntheticEvent<TextInputChangeEventData>' is not assignable to parameter of type 'SetStateAction<undefined>'.   Type 'NativeSyntheticEvent<TextInputChangeEventData>' provides no match for the signature '(prevState: undefined): undefined'.
all code is below
import React, { useState } from 'react'
import {
TextInput,
TouchableOpacity,
StyleSheet,
SafeAreaView,
Text,
View, Button,
} from 'react-native'
export default function App() {
const [pontoValue, setPontoValue] = useState()
const [dataValue, setDataValue] = useState()
return (
<SafeAreaView style={styles.container}>
<View style={styles.repositoryContainer}>
<TextInput
style={styles.input}
onChange={(text) => setPontoValue(text)}
/>
<TextInput
style={styles.input}
value={dataValue}
/>
<TouchableOpacity>
<Button
title="Calcular"
onPress={teste}>Converter
</Button>
</TouchableOpacity>
</View>
</SafeAreaView>
)
function teste() {
if (pontoValue) {
setDataValue(pontoValue.replace(/[ .]+/g, ''))
}
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignContent: 'center',
backgroundColor: '#7199c1',
},
repositoryContainer: {
marginBottom: 15,
marginHorizontal: 15,
backgroundColor: '#fff',
padding: 20,
},
input: {
height: 40,
padding: 5,
borderColor: 'gray',
borderWidth: 1,
},
buttonText: {
marginVertical: 11,
fontSize: 14,
fontWeight: 'bold',
color: '#fff',
backgroundColor: '#7159c1',
padding: 15,
},
})
onChange event returns an event object which has nativeEvent function which providers access to the following properties: { eventCount, target, text}
you need the text property, so you can use:
onChange={(event) => setPontoValue(event.nativeEvent.text)}
or
onChangeText={(text) => setPontoValue(text)}
I suggest you to use onChangeText prop.
onChangeText is a prop that gives you only text changes.
onChange on the other hand, passes an event.
So, try this
<TextInput
style={styles.input}
onChangeText={(text) => setPontoValue(text)}
/>
Also, always initialize your state variables.
const [pontoValue, setPontoValue] = useState('')
const [dataValue, setDataValue] = useState('')
It will reduce to chance of getting undefined errors.
Hope it works.

React Native - Why does the error only come out when the button is click when i assign the textInput to onchange?

I have some problem encounter while doing some project.
import React,{Component} from "react";
import {StyleSheet,Text,View,TextInput,
TouchableOpacity,Keyboard,KeyboardAvoidingView,Image} from "react-native";
import {reduxForm,Field} from "redux-form";
const validate = values =>{
const errors = {};
emailform = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/i
if(!values.email){
errors.email="not correct format for email address"
}else
if(!emailform.test(values.email)){
errors.email="not correct format for email address"
}
if(!values.password){
errors.password="please use at least 6 - 12 characters"
}else
if(values.password.length < 6 || values.password.length > 12){
errors.password="please use at least 6 - 12 characters"
}
return errors;
}
const myField = ({label, placeholder ,meta:{error, touched}, input:{onChange}}) =>{
return(
<View>
<Text style={styles.inputlabel}> {(label)} </Text>
<TextInput
style={styles.input}
onChangeText={onChange}
/>
{touched && (error && (<Text style={styles.errormessage}>{error}</Text>))}
</View>
);
}
const submit = values =>{
alert('Login Success!');
}
const myFormCom = props=>{
const {handleSubmit, invalid} = props;
return(
<KeyboardAvoidingView behavior="padding" style={styles.container}>
<View style={styles.logoContainer}>
<Image
style={styles.logo}
source={require('./src/images/Logo.png')}
/>
</View>
<View style={styles.formContainer}>
<Field
name="email"
component={myField}
label="Email"
/>
<Field
name="password"
component={myField}
label="Password"
/>
<TouchableOpacity
style={styles.buttonContainer}
onPress={handleSubmit(submit)}
//disabled={invalid}
>
<Text
style={styles.btnLabel}>
Sign In
</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
)
}
const LoginForm = reduxForm({
form: 'something',
validate
})(myFormCom);
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#faf8ff',
},
logoContainer:{
flexGrow: 1,
alignItems: 'center',
marginTop: 80,
},
logo:{
height: 100
},
formContainer:{
marginBottom: 30
},
input:{
height: 40,
backgroundColor: '#faf8ff',
marginLeft: 20,
marginRight: 20,
paddingLeft: 10,
borderWidth: 2,
borderColor: '#9d81d0',
borderRadius: 5
},
inputlabel:{
marginLeft: 20,
fontSize: 16,
fontWeight: '500',
marginBottom: 4
},
buttonContainer:{
backgroundColor: '#704db2',
marginLeft: 20,
marginRight: 20,
alignItems: 'center',
borderRadius: 5,
marginTop: 15
},
btnLabel:{
fontSize: 20,
color: '#fff',
fontWeight: 'bold',
padding: 10,
},
errormessage: {
color: 'red',
marginLeft: 20,
fontSize:14
}
});
export default LoginForm;
All I want is the button would be disable if their are some errors occur but my errors can't be shown when the button is not click. How is that? can someone explain to me? Sorry I'm not quite good in react native and JavaScript; I'm still learning my thing haha
Btw, in myField I declare there that it is onChange in the textInput so that will be change if the text is change right? but why does my error only show when i hit the sign in button? how do i get this thing right to show the error even if the button is not click yet.

Categories