React native component TextInput problem when I write goes crazy - javascript

I created a component called inputText.js, which serves to declare a particular input field according to my needs.
I use it inside login.js, passing it as Field props of redux-form.
The problem that when I begin to write even very slowly begins to start giving me problems, if I start writing faster, I get impatient, the text I write last in the field is mixed with the text already written and is found in the middle, even the stanchette that which indicates where the focus is inside the word is in the middle of the writing.
Link: Expo
Code: inputText.js
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { TextInput, IconButton, Colors } from 'react-native-paper';
import Icon from 'react-native-vector-icons/MaterialIcons';
const propTypes = {
mapElement: PropTypes.func,
onSubmitEditing: PropTypes.func,
onChangeText: PropTypes.func,
value: PropTypes.string,
placeholder: PropTypes.string,
maxLength: PropTypes.number,
keyboardType: PropTypes.string,
secureTextEntry: PropTypes.bool,
label: PropTypes.string,
};
const defaultProps = {
mapElement: n => {},
onSubmitEditing: () => {},
onChangeText: () => {},
value: '',
placeholder: '',
maxLength: 200,
keyboardType: 'default',
secureTextEntry: false,
label: '',
};
const styles = StyleSheet.create({
inputBox: {
width: 300,
//backgroundColor: 'rgba(255, 255,255,0.2)',
//borderRadius: 25,
//paddingHorizontal: 16,
//fontSize: 16,
//color: '#ffffff',
//marginVertical: 10,
},
icon: {
position: 'absolute',
top: 20,
right: 10,
},
});
class InputText extends Component<{}> {
constructor(props) {
super(props);
this.state = {
vPwd: props.secureTextEntry,
};
}
changePwdType = () => {
this.setState(prevState => ({
vPwd: !prevState.vPwd,
}));
};
render() {
const {
label,
placeholder,
secureTextEntry,
iconPassword,
keyboardType,
maxLength,
value,
onChangeText,
onSubmitEditing,
} = this.props;
const { vPwd } = this.state;
let icEye = vPwd ? 'visibility-off' : 'visibility';
return (
<View>
<TextInput
style={styles.inputBox}
placeholder={placeholder}
secureTextEntry={vPwd}
keyboardType={keyboardType}
maxLength={maxLength}
returnKeyType="next"
value={value}
onSubmitEditing={onSubmitEditing}
onChangeText={onChangeText}
label={label}
underlineColor="#fff"
theme={{
colors: {
primary: '#f5a442',
background: 'transparent',
placeholder: '#fff',
},
}}
/>
{secureTextEntry && iconPassword && (
<Icon
style={styles.icon}
name={icEye}
size={25}
onPress={this.changePwdType}
/>
)}
</View>
);
}
}
InputText.defaultProps = defaultProps;
InputText.propTypes = propTypes;
export default InputText;
Code: login.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import { Field, reduxForm } from 'redux-form';
import { HelperText } from 'react-native-paper';
import Logo from '../components/Logo';
import Form from '../components/Form';
import InputText from '../components/InputText';
import { Actions } from 'react-native-router-flux';
class Login extends Component<{}> {
signup() {
Actions.signup();
}
onSubmit = values => {
console.log(values);
};
renderTextInput = field => {
const {
meta: { touched, error },
label,
secureTextEntry,
iconPassword,
maxLength,
keyboardType,
placeholder,
input: { onChange, ...restInput },
} = field;
return (
<View>
<InputText
onChangeText={onChange}
maxLength={maxLength}
placeholder={placeholder}
keyboardType={keyboardType}
secureTextEntry={secureTextEntry}
iconPassword={iconPassword}
label={label}
{...restInput}
/>
{touched && error && (
<HelperText type="error" visible={true}>
{error}
</HelperText>
)}
</View>
);
};
render() {
const { handleSubmit } = this.props;
return (
<View style={styles.container}>
<Logo />
<View style={styles.inputContainerStyle}>
<Field
name="email"
label="Email"
placeholder="Email#host.com"
component={this.renderTextInput}
/>
<Field
name="password"
label="Password"
placeholder="***********"
secureTextEntry={true}
iconPassword={true}
component={this.renderTextInput}
/>
</View>
<TouchableOpacity
style={styles.button}
onPress={handleSubmit(this.onSubmit)}>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<View style={styles.signupTextCont}>
<Text style={styles.signupText}>Do not have an account yet?</Text>
<TouchableOpacity>
<Text style={styles.signupButton}> Signup</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#455a64',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
signupTextCont: {
flexGrow: 1,
alignItems: 'flex-end',
justifyContent: 'center',
paddingVertical: 16,
flexDirection: 'row',
},
signupText: {
color: 'rgba(255,255,255,0.6)',
fontSize: 16,
},
signupButton: {
color: '#ffffff',
fontSize: 16,
fontWeight: '500',
},
button: {
width: 300,
backgroundColor: '#1c313a',
borderRadius: 25,
marginVertical: 10,
paddingVertical: 13,
},
buttonText: {
fontSize: 16,
fontWeight: '500',
color: '#ffffff',
textAlign: 'center',
},
inputContainerStyle: {
backgroundColor: 'rgba(255, 255, 255, 0.15)',
padding: 5,
paddingBottom: 10,
borderRadius: 5,
},
});
const validate = values => {
const errors = {};
if (!values.email) {
errors.email = 'Email is required';
}
if (!values.password) {
errors.password = 'Password is required';
}
return errors;
};
export default reduxForm({
form: 'login',
validate,
})(Login);

Related

When putting new value into an input field erases a previous one

With my current code, I have two input fields and a drop down menu. When ever a value is placed into the field or modified, it clears the rest of the fields. The only one that will stay consistent is the drop down menu. I have suspicions that my useEffect hooks may be doing something, but I'm quite unsure of why. Any suggestions would be great.
(FYI: storeArtic is the push to firebase)
CustomScreen.js
import React, { useState } from "react";
import { StyleSheet, Text, Keyboard, View, TouchableWithoutFeedback } from "react-native";
import { Button, Input } from "react-native-elements";
import { Dropdown } from "react-native-material-dropdown";
import { storeArtic } from '../helpers/fb-settings';
const CustomScreen = ({ route, navigation }) =>{
//create a screen with the ability to add a picture with text to the deck of artic cards
//add check box solution for selection of word type (maybe bubbles, ask about this)
const articDrop = [
{value: 'CV'},
{value: 'VC'},
{value: 'VV'},
{value: 'VCV'},
{value: 'CVCV'},
{value: 'C1V1C1V2'},
{value: 'C1V1C2V2'},
];
const [articCard, setCard] = useState({
word: '',
imageUrl: '',
aType:'',
cType: '',
mastery: false
})
return(
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View>
<Text>Please enter the information of your custom card!</Text>
<Input
placeholder="Enter valid image url"
value={articCard.imageUrl}
autoCorrect={false}
onChangeText={(val) => setCard({ imageUrl: val })}
/>
<Input
placeholder="Enter word or phrase"
value={articCard.word}
autoCorrect={false}
onChangeText={(val) =>
setCard({ word: val, aType: val.charAt(0).toUpperCase(), mastery: false})
}
/>
<Dropdown
value={articCard.cType}
onChangeText={(text) => setCard({cType: text})}
label="Artic Type"
data={articDrop}
/>
<Button
//this will save the cards to the database
title="Save"
onPress={() => {
storeArtic({articCard})
}}
/>
<Button
title="Clear"
onPress={() => {
setCard({word: '', aType: '', cType: '', imageUrl: '', mastery: false});
navigation.navigate('Home');
}}
/>
</View>
</TouchableWithoutFeedback>
)
}
export default CustomScreen;
HomeScreen.js
import React, { useState, useEffect } from "react";
import { StyleSheet, Text, Keyboard, TouchableOpacity, View, TouchableWithoutFeedback, Image } from "react-native";
import { Button } from "react-native-elements";
import { Feather } from "#expo/vector-icons";
import { initArticDB, setupArticListener } from '../helpers/fb-settings';
const HomeScreen = ({route, navigation}) => {
const [ initialDeck, setInitialDeck] = useState([]);
useEffect(() => {
try {
initArticDB();
} catch (err) {
console.log(err);
}
setupArticListener((items) => {
setInitialDeck(items);
});
}, []);
useEffect(() => {
if(route.params?.articCard){
setCard({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
}
}, [route.params?.articType] );
navigation.setOptions({
headerRight: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate('Settings')
}
>
<Feather
style={styles.headerButton}
name="settings"
size={24}
color="#fff"
/>
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity
onPress={() =>
navigation.navigate('About')
}
>
<Text style={styles.headerButton}> About </Text>
</TouchableOpacity>
),
});
return(
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.container}>
<Text style={styles.textmenu}>Welcome to Artic Cards</Text>
<Text style={styles.textsubmenu}>Press Start to Begin!</Text>
<Image source={require('../assets/5-snowflake-png-image.png')}
style={{width: 300, height: 300, alignSelf: 'center'}}/>
<Button
title="Start"
style={styles.buttons}
onPress={() => navigation.navigate('Cards',
{passDeck: initialDeck})}
/>
<Button
title="Progress"
style={styles.buttons}
onPress={() => navigation.navigate('Progress')}
/>
<Button
title="Customize"
style={styles.buttons}
onPress={() => navigation.navigate('Customize')}
/>
</View>
</TouchableWithoutFeedback>
);
};
const styles = StyleSheet.create({
container: {
padding: 10,
backgroundColor: '#E8EAF6',
flex: 1,
justifyContent: 'center'
},
textmenu: {
textAlign: 'center',
fontSize: 30
},
textsubmenu:{
textAlign: 'center',
fontSize: 15
},
headerButton: {
color: '#fff',
fontWeight: 'bold',
margin: 10,
},
buttons: {
padding: 10,
},
inputError: {
color: 'red',
},
input: {
padding: 10,
},
resultsGrid: {
borderColor: '#000',
borderWidth: 1,
},
resultsRow: {
flexDirection: 'row',
borderColor: '#000',
borderBottomWidth: 1,
},
resultsLabelContainer: {
borderRightWidth: 1,
borderRightColor: '#000',
flex: 1,
},
resultsLabelText: {
fontWeight: 'bold',
fontSize: 20,
padding: 10,
},
resultsValueText: {
fontWeight: 'bold',
fontSize: 20,
flex: 1,
padding: 10,
},
});
export default HomeScreen;
Unlike class based setState, with functional components when you do setState, it will override the state with what you provide inside setState function. It is our responsibility to amend state (not overrite)
So, if your state is an object, use callback approach and spread previous state and then update new state.
Like this
<Input
placeholder="Enter valid image url"
value={articCard.imageUrl}
autoCorrect={false}
onChangeText={(val) => setCard(prev => ({ ...prev, imageUrl: val }))} //<----- like this
/>
Do the same for all your inputs.

OnPress that redirect to other page

I am trying to develop an application to learn react native and I am stuck with the login/register.
I have a register.js that works properly, as I have tested it before, and I wanted to add a resiter button to redirect to the register page from the login one.
From the UserLogin.js, the button is this one:
<TouchableOpacity
onPress={() => navigate('Register')}
style={{width:200,padding:10,backgroundColor:'pink',alignItems:'center'}}>
<Text style={{color:'black'}}>Register</Text>
</TouchableOpacity>
UserLogin.js
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,TouchableOpacity,TextInput,Button,Keyboard
} from 'react-native';
import { StackNavigator } from 'react-navigation';
class UserLogin extends React.Component {
constructor(props){
super(props)
this.state={
userEmail:'',
userPassword:''
}
}
login = () =>{
const {userEmail,userPassword} = this.state;
let reg = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
if(userEmail==""){
//alert("Please enter Email address");
this.setState({email:'Please enter Email address'})
}
else if(reg.test(userEmail) === false)
{
//alert("Email is Not Correct");
this.setState({email:'Email is Not Correct'})
return false;
}
else if(userPassword==""){
this.setState({email:'Please enter password'})
}
else{
fetch('http://192.168.1.47/login.php',{
method:'post',
header:{
'Accept': 'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
// we will pass our input data to server
email: userEmail,
password: userPassword
})
})
.then((response) => response.json())
.then((responseJson)=>{
if(responseJson == "ok"){
// redirect to profile page
alert("Successfully Login");
//this.props.navigation.navigate("Profile");
}else{
alert("Wrong Login Details");
}
})
.catch((error)=>{
console.error(error);
});
}
Keyboard.dismiss();
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.container}>
<Text style={{padding:10,margin:10,color:'red'}}>{this.state.email}</Text>
<TextInput
placeholder="Enter Email"
style={{width:200, margin:10}}
onChangeText={userEmail => this.setState({userEmail})}
/>
<TextInput
placeholder="Enter Password"
style={{width:200, margin:10}}
onChangeText={userPassword => this.setState({userPassword})}
/>
<TouchableOpacity
onPress={this.login}
style={{width:200,padding:10,backgroundColor:'magenta',alignItems:'center'}}>
<Text style={{color:'white'}}>Login</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => navigate('Register')}
style={{width:200,padding:10,backgroundColor:'pink',alignItems:'center'}}>
<Text style={{color:'black'}}>Register</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
export default UserLogin
AppRegistry.registerComponent('login', () => login);
register.js
import React, { Component } from 'react';
import { View, Text, StyleSheet, TextInput, TouchableOpacity, ActivityIndicator, Platform } from 'react-native';
class Register extends React.Component
{
constructor()
{
super();
this.state = { first_name: '', last_name: '', email: '', password: '', loading: false, disabled: false }
}
saveData = () =>
{
this.setState({ loading: true, disabled: true }, () =>
{
fetch('http://192.168.1.47/user_registration.php',
{
method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(
{
first_name: this.state.first_name,
last_name: this.state.last_name,
email: this.state.email,
password: this.state.password,
})
}).then((response) => response.json()).then((responseJson) =>
{
//Faire une redirection evrs le profile de l'utilisateur
alert(responseJson);
this.setState({ loading: false, disabled: false });
}).catch((error) =>
{
console.error(error);
this.setState({ loading: false, disabled: false });
});
});
}
render()
{
return(
<View style = { styles.container }>
<TextInput underlineColorAndroid = "transparent" placeholder = "Your First Name" style = { styles.textInput } onChangeText = {(text) => this.setState({ first_name: text })}/>
<TextInput underlineColorAndroid = "transparent" placeholder = "Your Last Name" style = { styles.textInput } onChangeText = {(text) => this.setState({ last_name: text })}/>
<TextInput underlineColorAndroid = "transparent" placeholder = "Your Email adress" style = { styles.textInput } onChangeText = {(text) => this.setState({ email: text })}/>
<TextInput underlineColorAndroid = "transparent" placeholder = "Your Password" style = { styles.textInput } onChangeText = {(text) => this.setState({ password: text })}/>
<TouchableOpacity disabled = { this.state.disabled } activeOpacity = { 0.8 } style = { styles.Btn } onPress = { this.saveData }>
<Text style = { styles.btnText }>Sign up</Text>
</TouchableOpacity>
{
(this.state.loading)
?
(<ActivityIndicator size = "large" />)
:
null
}
</View>
);
}
}
const styles = StyleSheet.create(
{
container:
{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#eee',
paddingHorizontal: 25,
paddingTop: (Platform.OS == 'ios') ? 20 : 0
},
textInput:
{
height: 40,
borderWidth: 1,
borderColor: 'grey',
marginVertical: 5,
alignSelf: 'stretch',
padding: 8,
fontSize: 16
},
Btn:
{
backgroundColor: 'rgba(0,0,0,0.6)',
alignSelf: 'stretch',
padding: 10,
marginTop: 10,
marginBottom: 25
},
btnText:
{
textAlign: 'center',
color: 'white',
fontSize: 16
}
});
export default Register
Navigation.js
import Search from '../Components/Search';
import ProductDetail from '../Components/ProductDetail';
//import UserAccount from '../Components/UserAccount';
import UserLogin from '../Components/UserLogin';
//import UserRegistration from '../Components/UserRegistration';
import Transaction from '../Components/Transaction';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import React from 'react';
import { Image , Text, TouchableOpacity } from 'react-native';
const SearchStackNavigator = createStackNavigator({
Rechercher : {
screen: Search,
navigationOptions: ({ navigate, navigation }) => ({
title:'Rechercher',
headerTitleStyle: {
fontWeight: 'bold',
color: 'white',
marginLeft:5,
},
headerStyle: {
backgroundColor: '#FF6100',
},
headerLeft: (
<TouchableOpacity
onPress={() => navigation.navigate('Rechercher')}>
<Image
style={{
width: 35,
height: 35,
marginLeft: 25,
}}
source={require('../Images/logo.jpg')}
/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
onPress={() => navigation.navigate('Account')}>
<Image
style={{
width: 35,
height: 35,
marginRight: 25,
}}
source={require('../Images/user.png')}
/>
</TouchableOpacity>
)
})
},
ProductDetail : {
screen: ProductDetail,
navigationOptions: ({ navigate, navigation }) => ({
title:'Détail du produit',
headerTitleStyle: {
fontWeight: 'bold',
color: 'white',
marginLeft:5,
},
headerStyle: {
backgroundColor: '#FF6100',
},
headerLeft: (
<TouchableOpacity
onPress={() => navigation.navigate('Rechercher')}>
<Image
style={{
width: 35,
height: 35,
marginLeft: 25,
}}
source={require('../Images/logo.jpg')}
/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
onPress={() => navigation.navigate('Account')}>
<Image
style={{
width: 35,
height: 35,
marginRight: 25,
}}
source={require('../Images/user.png')}
/>
</TouchableOpacity>
)
})
},
Account: {
//screen: UserRegistration,
screen: UserLogin,
navigationOptions: ({ navigate, navigation }) => ({
title:'Compte utilisateur',
headerTitleStyle: {
fontWeight: 'bold',
color: 'white',
marginLeft:5,
},
headerStyle: {
backgroundColor: '#FF6100',
},
headerLeft: (
<TouchableOpacity
onPress={() => navigation.navigate('Rechercher')}>
<Image
style={{
width: 35,
height: 35,
marginLeft: 25,
}}
source={require('../Images/logo.jpg')}
/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
onPress={() => navigation.navigate('Account')}>
<Image
style={{
width: 35,
height: 35,
marginRight: 25,
}}
source={require('../Images/user.png')}
/>
</TouchableOpacity>
)
})
},
Transaction: {
screen: Transaction,
navigationOptions: ({ navigate, navigation }) => ({
title:'Transaction',
headerTitleStyle: {
fontWeight: 'bold',
color: 'white',
marginLeft:5,
},
headerStyle: {
backgroundColor: '#FF6100',
},
headerLeft: (
<TouchableOpacity
onPress={() => navigation.navigate('Rechercher')}>
<Image
style={{
width: 35,
height: 35,
marginLeft: 25,
}}
source={require('../Images/logo.jpg')}
/>
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
onPress={() => navigation.navigate('Account')}>
<Image
style={{
width: 35,
height: 35,
marginRight: 25,
}}
source={require('../Images/user.png')}
/>
</TouchableOpacity>
)
})
},
})
export default createAppContainer(SearchStackNavigator)
Navigation.js is located on a folder named Navigation.
The two other files are on the same folder (The components one).
Can someone help me fixe it ? I don't think it's complicated, but there is something I didn't understand, I think.
Thank you in advance.
Noémie.
Your Register, and Login screens have to be listed as routes in your
stack-navigation ... so you can get access to navigation object to use
it for navigation – Hend El-Sahli

How to rerender the page on alert ok button

Here in my code I am trying to reload the page on Alert ok button . But its not working . How can I rerender the page on ok button , this is written on same page that I have to reload .
In my code I am sung form and inputfield compont for my login screen . All code is there below . I am tryning to is , when I am getting any respons like wrong username and password in alere then ok button I have to clear my form field . While here ists not happning . For this I am deleting my value mannully.
Please sugget .
import React from 'react';
import { Alert, Dimensions, ImageBackground, Text, View, TouchableOpacity, Platform , StatusBar} from 'react-native';
import Formbox from './ui/form';
import { RegularText, } from './ui/text';
import pkg from '../../package';
import _ from 'lodash';
import { LOGIN_BACKGROUND , LOGIN_BACKGROUND_DARK} from '../images'
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
import parentStyle from '../themes/parent.style'
import LottieView from 'lottie-react-native';
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
const styles = {
imgBG: { width: '100%', height: '100%' },
mainContainer: {
flex: 1,
alignItems: 'stretch',
justifyContent: 'flex-start',
height: deviceHeight,
paddingLeft: 20,
paddingRight: 20
},
logoContainer: { justifyContent: 'center', alignItems: 'center', background: 'red', marginTop: -50 },
logoView: {
borderWidth: 3,
borderColor: '#FFFFFF',
borderRadius: 4,
zIndex: -1,
...Platform.select({
ios: {
shadowOpacity: 0.45,
shadowRadius: 3,
shadowColor: '#090909',
shadowOffset: { height: 1, width: 0 }
},
android: {
elevation: 3
}
})
}
};
export default class Login extends React.Component {
constructor(props) {
super(props);
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (this.props.error) {
if (this.props.error.graphQLErrors[0] !== undefined) {
const errorDetails = _.map(_.split(this.props.error.graphQLErrors[0].message, '#'), _.trim)
const header = errorDetails[0];
const message = errorDetails[1];
Alert.alert(header, message, [{
text: 'OK',
onPress: () => this.props.navigation.push('Auth')
},]);
} else {
Alert.alert('Network Error', this.props.error.networkError.message, [{
text: 'OK',
onPress: () => this.props.navigation.navigate('Auth')
},]);
}
}
}
componentDidMount(){
StatusBar.setBarStyle('dark-content');
}
render() {
let loginForm = [
{ label: 'Username', icon: 'person', type: 'text' },
{ label: 'Password', icon: 'key', type: 'password' }
];
let submitBtn = { label: 'Login', OnSubmit: this.props.onLogin };
let appliedTheme = this.props.theme;
let appliedMode = this.props.mode;
return (
<ImageBackground source={appliedMode === 'light' ? LOGIN_BACKGROUND : LOGIN_BACKGROUND_DARK} style={styles.imgBG}>
<View style={styles.mainContainer}>
<View style={{ flexDirection: 'column', alignContent: 'center', justifyContent: 'center', flex: 1 }}>
<View style={{ flex: 0.75, justifyContent: 'center' }}>
<RegularText text={'Welcome,'} textColor='#57606F' style={{ fontSize: hp('5%') }} />
<RegularText text={'Sign in to continue'} textColor='#ABAFB7' style={{ fontSize: hp('3.5%') }} />
</View>
<View style={{ flex: 2 }}>
<View style={{ flex: 2 }}>
<Formbox
theme={parentStyle[appliedTheme] ? parentStyle[appliedTheme][appliedMode].primaryButtonColor : undefined}
mode={this.props.mode}
formFields={loginForm}
submit={submitBtn}
that={this}
mutation={this.props.token}
/>
<View style={{ height: hp(20), zIndex:10, top: -25}}>
{this.props.loading && (
<LottieView source={require('./animations/login_authentication.json')} autoPlay loop />
)}
</View>
<View style={{top:-70, zIndex:10}}>
{false && <View style={{ alignItems: 'center' }}>
<RegularText text={`v${pkg.version}`} textColor='#ABAFB7' style={{ fontSize: hp('2%') }} />
</View>}
<View style={{ alignItems: 'flex-end' }}>
<View style={{ flexDirection: 'row' }}>
<RegularText text={`New User?`} textColor='#4A494A' style={{ fontSize: hp('2%') }} />
<TouchableOpacity>
<RegularText text={` REGISTER`} textColor={parentStyle[appliedTheme] ? parentStyle[appliedTheme][appliedMode].primaryButtonColor : '#fff'} style={{ fontSize: hp('2%'), fontWeight: 'bold' }} />
</TouchableOpacity>
</View>
</View>
</View>
</View>
</View>
</View>
</View>
</ImageBackground>
);
}
}
////// Form ,js
import React, { Component } from 'react';
import { View, Platform, Dimensions } from 'react-native';
import { PrimaryBtn,PrimaryAbsoluteGradientBtn } from './buttons';
import { InputField, PasswordField } from './inputField';
import { Form } from 'native-base';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;
export default class Formbox extends Component {
constructor(props) {
super(props);
}
OnSubmit() {
let { formFields, that, submit, mutation } = this.props;
submit.OnSubmit.bind(that, formFields, mutation)();
}
OnChange(field, target) {
this.props.formFields.forEach(function (formField, indx) {
if (formField.label === field.label) {
formField.value = target;
}
});
}
renderFields(field, indx) {
let { label, icon, type } = field;
if (label && icon) {
if (type === 'password') {
return <PasswordField key={label + indx} type={type ? type : ''} label={label} icon={icon}
OnChange={this.OnChange} that={this} />;
}
return <InputField key={label + indx} type={type ? type : ''} label={label} icon={icon} OnChange={this.OnChange}
that={this} />;
}
}
render() {
let { formFields, submit, that , theme, mode} = this.props;
return (
<View style={{ width: '100%' }}>
<Form style={{ width: '95%' }}>
{formFields.map((field, indx) => this.renderFields(field, indx))}
<View style={{ marginTop: 60 }}>
<PrimaryAbsoluteGradientBtn label={submit.label} OnClick={this.OnSubmit} that={this} backgroundColor={theme}/></View>
</Form>
</View>
);
}
}
/// input fields js
import React, { Component } from 'react';
import { Icon, Input, Item, Label } from 'native-base';
import { View } from 'react-native';
import { DoNothing } from '../services/services';
class InputField extends Component {
constructor(props) {
super(props);
}
render() {
let { label, OnChange, icon, that,type, keyboardType } = this.props;
return (
<View>
<Item floatingLabel>
{icon && <Icon active name={icon}/>}
{label && <Label>{label}</Label>}
<Input
secureTextEntry={type === 'password'}
onChangeText={OnChange ? (e) => OnChange.bind(that, this.props, e)() : DoNothing.bind(this)}
keyboardType={keyboardType || 'default'}
autoCapitalize = 'none'
autoCorrect={false}
/>
</Item>
</View>
);
}
}
class PasswordField extends Component {
constructor(props) {
super(props);
this.state = {
isMasked: true
};
}
_toggleMask = () => {
this.setState({
isMasked: !this.state.isMasked
});
};
render() {
let { label, OnChange, icon, that, type } = this.props;
const { isMasked } = this.state;
return (
<View>
<Item floatingLabel>
{icon && <Icon active name={icon}/>}
<Label>{label}</Label>
<Input
autoCapitalize = 'none'
secureTextEntry={isMasked}
onChangeText={OnChange ? (e) => OnChange.bind(that, this.props, e)() : DoNothing.bind(this)}
/>
<Icon name={isMasked ? "md-eye-off" : "md-eye"} active type="Ionicons" onPress={() => this._toggleMask()}/>
</Item>
</View>
);
}
}
const styles = {
dark: {
color: "#000000"
},
light: {
color: "#EAEAEA"
}
}
export { InputField, PasswordField };
You can either do :
onPress: () => this.props.navigation.push('Auth')
or do something like :
onPress: () => this.setState({name:'random'})
These both will trigger re rendering, Hope it helps. feel free for doubts

How to show error message on react native using redux

i am using redux in my react native app .
my problem is how to show the error message that appear in the terminal to the render .
i tried to use {this.props.error} and nothing will show up
Actions
import * as actionTypes from "./Types";
export const setErrors = errors => ({
type: actionTypes.SET_ERRORS,
payload: errors
});
export const resetError = () => {
return async dispatch => {
dispatch({
type: actionTypes.RESET_ERROR,
payload: []
});
};
};
Reducers
import * as actionTypes from "../actions/Types";
import { SET_ERRORS, RESET_ERROR } from "../actions/Types";
const initialState = {
errors: [],
reset: ""
};
const reducer = (state = initialState, action) => {
switch (action.type) {
case SET_ERRORS:
console.log("from reducer");
console.log("errrrro", action.payload);
return {
...state,
errors: Object.keys(action.payload).map(
key => `${key}: ${action.payload[key]}`
)
};
case RESET_ERROR:
return {
...state,
errors: action.payload
};
default:
return state;
}
};
export default reducer;
this is my index.js
import React, { Component } from "react";
import { connect } from "react-redux";
import * as actionCreators from "../../store/actions";
import {
StyleSheet,
Text,
View,
TextInput,
Button,
TouchableHighlight,
Image
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
class Login extends Component {
state = {
username: "",
password: ""
};
resetState = () => {
this.setState({ password: null });
};
errors = () => {
this.props.errors;
};
Login = () => {
this.props.login(this.state, this.props.navigation);
this.resetState();
};
render() {
return (
<LinearGradient
colors={["#002d44", "#001724"]}
style={{ flex: 1 }}
start={[0, 0]}
end={[1, 0]}
>
<View style={styles.container}>
<Text>{error}</Text>
<View style={styles.inputContainer}>
<Image
style={styles.inputIcon}
source={{
uri:
"https://img.icons8.com/ios/80/000000/identification-documents-filled.png"
}}
/>
<TextInput
style={styles.inputs}
autoCapitalize="none"
placeholder="اسم المستخدم"
onChangeText={username => this.setState({ username })}
value={this.state.username}
/>
</View>
<View style={styles.inputContainer}>
<Image
style={styles.inputIcon}
source={{
uri: "https://img.icons8.com/ios/80/000000/lock-2-filled.png"
}}
/>
<TextInput
style={styles.inputs}
placeholder="كلمة المرور"
secureTextEntry={true}
onChangeText={password => this.setState({ password })}
value={this.state.password}
/>
</View>
<TouchableHighlight
style={[styles.buttonContainer, styles.loginButton]}
onPress={this.Login}
>
<Text style={{ color: "#fff", fontSize: 15 }}>دخول</Text>
</TouchableHighlight>
<TouchableHighlight
style={{}}
onPress={() => this.props.navigation.replace("Signup")}
>
<Text style={{ color: "#00F7EA", fontSize: 15 }}>تسجيل</Text>
</TouchableHighlight>
</View>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
inputContainer: {
borderBottomColor: "#F5FCFF",
backgroundColor: "#FFFFFF",
borderRadius: 30,
borderBottomWidth: 1,
width: 250,
height: 45,
marginBottom: 20,
flexDirection: "row",
alignItems: "center"
},
inputs: {
height: 45,
marginLeft: 16,
fontSize: 15,
textAlign: "center",
borderBottomColor: "#FFFFFF",
flex: 1
},
inputIcon: {
width: 30,
height: 30,
marginLeft: 15,
justifyContent: "center"
},
buttonContainer: {
height: 45,
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginBottom: 20,
width: 250,
borderRadius: 30,
borderWidth: 0.8,
borderColor: "#d6d7da"
},
loginButton: {
backgroundColor: "transparent"
},
buttonDisabled: {
backgroundColor: "#e7e7e7"
},
loginText: {
color: "white"
}
});
const mapStateToProps = state => ({
user: state.authReducer.user,
loading: state.devicesReducer.loading,
errors: state.errorReducer.errors
});
const mapDispatchToProps = dispatch => ({
login: (userData, navigation) =>
dispatch(actionCreators.login(userData, navigation)),
checkForExpiredToken: navigation =>
dispatch(actionCreators.checkForExpiredToken(navigation))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login);
the error message that showing on the terminal
from reducer
errrrro Object {
"password": Array [
"This field may not be blank.",
],
"username": Array [
"This field may not be blank.",
],
}
from reducer
errrrro [Error: Request failed with status code 400]

DrawerNavigation - Can't change header colour

I'm working on a react native application, and using a DrawerNavigator. Unfortunately I'm not able to change the colour of the header, my SideMenu component looks like this:
import React from 'react';
import {
TouchableHighlight,
View,
ScrollView,
Image,
Platform,
StyleSheet
} from 'react-native';
import {NavigationActions} from 'react-navigation';
import {
RkStyleSheet,
RkText,
RkTheme
} from 'react-native-ui-kitten';
import { MainRoutes } from '../routes/routes';
import { MaterialCommunityIcons } from 'react-native-vector-icons';
import { connect } from 'react-redux';
const mapStateToProps = (state) => {
return {
}
}
class SideMenu extends React.Component {
static navigationOptions = ({navigation}) => {
const { state, setParams } = navigation;
return {
headerTintColor: 'red',
headerLeft: null,
headerStyle: { backgroundColor: 'rgba(77, 90, 139, 1)', shadowColor: 'transparent', borderBottomWidth: 0},
};
};
constructor(props) {
super(props);
this._navigateAction = this._navigate.bind(this);
}
_navigate(route) {
let resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({routeName: route.id})
]
});
this.props.navigation.dispatch(resetAction)
}
_renderIcon() {
// if (RkTheme.current.name === 'light')
// return <Image style={styles.icon} source={require('../../assets/images/smallLogo.png')}/>;
// return <Image style={styles.icon} source={require('../../assets/images/smallLogoDark.png')}/>
}
handlePress = (route, index) => {
const { navigation } = this.props;
navigation.navigate(route.id);
}
render() {
let menu = MainRoutes.map((route, index) => {
return (
<TouchableHighlight
style={styles.container}
key={route.id}
underlayColor={RkTheme.current.colors.button.underlay}
activeOpacity={1}
onPress={() => this.handlePress(route, index)}>
<View style={styles.content}>
<View style={styles.content}>
<MaterialCommunityIcons size={25} style={{color: 'white'}} name={route.icon} />
<View style={{flex: 1, alignItems: 'left', paddingLeft: 15}}>
<RkText style={{color:'white'}}>{route.title}</RkText>
</View>
</View>
</View>
</TouchableHighlight>
)
});
return (
<View style={styles.root}>
<ScrollView
showsVerticalScrollIndicator={false}>
<View style={[styles.container, styles.content], {borderTopWidth: 0}}>
{this._renderIcon()}
</View>
{menu}
</ScrollView>
</View>
)
}
}
let styles = RkStyleSheet.create(theme => ({
container: {
height: 80,
paddingHorizontal: 16,
borderTopWidth: StyleSheet.hairlineWidth,
borderColor: 'white',
backgroundColor: 'rgba(77, 90, 139, 1)'
},
root: {
paddingTop: Platform.OS === 'ios' ? 20 : 0,
backgroundColor: 'rgba(77, 90, 139, 1)'
},
content: {
flex: 1,
flexDirection: 'row',
alignItems: 'center'
},
icon: {
marginRight: 13,
}
}));
export default connect(mapStateToProps)(SideMenu);
As you can see I do set the style of the header in the NavigationOptions like I do with the other components but the header stays the same colour.
Could this be because the DrawerNavigator is nested within a TabNavigator?
Thanks and really appreciate any help.
The Navigators are defined as so:
onst SettingsDrawerNavigator = DrawerNavigator(
{
SettingsScreen: {
screen: SettingsScreen
}
},
{
//initialRouteName: 'SettingsScreen',
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
contentComponent: (props) => <SideMenu {...props}/>
}
);
export default TabNavigator(
//Adds elements to the navigator at the bottom.
{
//Other tabs.
Account: {
screen: SettingsDrawerNavigator,
}
},
{
navigationOptions: ({ navigation }) => ({
initialRouteName: 'Home',
tabBarIcon: ({ focused }) => {
const { routeName } = navigation.state;
let iconName;
return (
// <Button badge vertical>
// <Badge ><Text>51</Text></Badge>
<Ionicons
name={iconName}
size={24}
style={{ marginBottom: -3 }}
color={focused ? Colors.tabIconSelected : Colors.tabIconDefault}
/>
// </Button>
);
},
}),
tabBarOptions: {
inactiveBackgroundColor: 'transparent',
activeBackgroundColor: 'transparent',
showLabel: false,
style: {
backgroundColor: '#4d5a8b',
}
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}
);
Adding a header to the DrawerNavigator resulted in the following (red). I'm trying to set the white background at the top to red.

Categories

Resources