How to pass form data to another page in react native? - reactjs

I've created a login page like this:
class Login extends Component {
render() {
const { navigate } = this.props.navigation
return (
<View style={{ flex: 1 }}>
<View style={styles.container}>
<View style={styles.container1}>
<TextInput
style={{ width: 190, color: 'white' }}
placeholder="User Name"
placeholderTextColor="#f9f9f9"
underlineColorAndroid="#f9f9f9"
/>
<TextInput
placeholder="Password"
secureTextEntry
returnKeyType="go"
ref={input => (this.passwordInput = input)}
style={{ width: 190, color: 'white' }}
placeholderTextColor="#f9f9f9"
underlineColorAndroid="#f9f9f9"
/>
<TouchableOpacity style={{ top: 10 }}>
<Button
color="#314561"
onPress={() => navigate('HomePage')}
title="Login"
/>
</TouchableOpacity>
</View>
</View>
</View>
)
}
}
export default Login
Now I need to pass the username to the home page. I've referred a number of resources and didn't got any solutions. How can I pass the username to home page?

First save your input value to some variables using onChangeText
<TextInput
value= {this.state.userName}
onChangeText = {(text)=>{
this.setState({userName:text});
}
/>
Then you can pass the value ,
<Button
onPress={() => navigate('HomePage',{"userName":this.state.userName})} // you can pass objects
title="Login"
/>

Do the following changes :
In Login component :
Username Field
<TextInput
style={{width:190,color:'white'}}
placeholder="User Name"
placeholderTextColor="#f9f9f9"
underlineColorAndroid='#f9f9f9'
onChangeText=
{(username)=>this.setState({username})}
/>
Button :
<TouchableOpacity style={{top:10}}>
<Button
color="#314561"
onPress={() => navigate('HomePage'), { username: this.state.username }}
title="Login"/>
</TouchableOpacity>
In Home component:
e.g. render method
render(){
const {state} = this.props.navigation;
console.og(state.params.username)
}
Update :
In login constructor,initialise state
constructor(){
super();
this.state = {};
}

class Login extends Component {
constructor(props) {
super(props);
this.state = {
userName:"",
password:""
};
}
updateUserName = (name) =>{
this.setState({
userName:name,
})
}
updatePwd = (pwd) =>{
this.setState({
password:pwd,
})
}
render() {
const { navigate } = this.props.navigation
return (
<View style={{ flex: 1 }}>
<View style={styles.container}>
<View style={styles.container1}>
<TextInput
style={{ width: 190, color: 'white' }}
placeholder="User Name"
placeholderTextColor="#f9f9f9"
underlineColorAndroid="#f9f9f9"
onChangeText={(name) => this.updateUserName(name)}
value={this.state.userName}
/>
<TextInput
placeholder="Password"
secureTextEntry
returnKeyType="go"
ref={input => (this.passwordInput = input)}
style={{ width: 190, color: 'white' }}
placeholderTextColor="#f9f9f9"
underlineColorAndroid="#f9f9f9"
onChangeText={(pwd) => this.updatePwd(pwd)}
value={this.state.password}
/>
<TouchableOpacity style={{ top: 10 }}>
<Button
color="#314561"
onPress={() => navigate('HomePage',{userName:this.state.userName})}
title="Login"
/>
</TouchableOpacity>
</View>
</View>
</View>
)
}
}
export default Login
file : homePage.js
constructor(props) {
super(props);
const { params } = this.props.navigation.state;
var data = params.userName;
this.state = {
userName : data
};
}

Related

React Native Update Parent Array from Child Component

I am having trouble updating an array that is passed as a prop into my child component. I have searched around but haven't found an answer that can directly solve my problem. My code is as follows:
App.js
import React, { Component } from 'react';
import { StyleSheet, Text, View, SafeAreaView } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import AddMedication from "./src/AddMedication";
import MedicationList from './src/MedicationList';
const Stack = createNativeStackNavigator();
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
medications: [],
}
this.addMedication = this.addMedication.bind(this);
}
addMedication = (name, dosage, measurement, timesDaily) => {
console.log("Medication added.")
var newItem = {name: name, dosage: dosage, measurement: measurement, timesDaily: timesDaily}
this.setState({
medications: [...this.state.medications, newItem]
})
}
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Medication List">
{(props) => <MedicationList {...props} medications={this.state.medications} />}
</Stack.Screen>
<Stack.Screen name="Add New Medication">
{(props) => <AddMedication {...props} addMedication={this.addMedication} />}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
);
}
}
This is the home screen where I am trying to display the array but nothing shows up
MedicationList.js
class MedicationList extends Component {
constructor(props) {
super(props);
this.state = {
tableHead: ['Name', 'Dosage', 'Times Daily', 'Prescriber', 'For Diagnosis'],
}
}
medication = ({ item }) => {
<View style={{ flexDirection: 'row' }}>
<View style={{ width: 50, backgroundColor: 'lightyellow'}}>
<Text style={{ fontSize: 16, fontWeight: 'bold', textAlign: 'center'}}>{item.name}</Text>
</View>
<View style={{ width: 400, backgroundColor: 'lightpink'}}>
<Text style={{ fontSize: 16, fontWeight: 'bold' , textAlign: 'center'}}>{item.dosage}{item.selectedMeasurement}</Text>
</View>
<View style={{ width: 400, backgroundColor: 'lavender'}}>
<Text style={{ fontSize: 16, fontWeight: 'bold' , textAlign: 'center'}}>{item.timesDaiy}</Text>
</View>
</View>
}
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', marginTop: '10%'}}>
<Button
title="+ Add New Medication"
onPress={() => {
/* 1. Navigate to the Details route with params */
this.props.navigation.navigate('Add New Medication', {
medications: this.props.medications,
});
}}
/>
<FlatList
data={this.props.medications}
renderItem={this.medication}
/>
</View>
);
}
}
This is where I click the add button to update the medications array
AddMedication.js
class AddMedication extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
dosage: 0,
selectedMeasurement: "mg",
timesDaily: '',
prescriber: '',
forDiagnoses: '',
instructions: '',
validity: false,
};
}
setName = (name) => {
let isValid = this.isFormValid();
this.setState({ name: name, validity: isValid });
}
setDosage = (dosage) => {
let isValid = this.isFormValid();
this.setState({ dosage: dosage, validity: isValid });
}
setMeasurement = (measurement) => {
this.setState({ selectedMeasurement: measurement });
}
setTimesDaily = (timesDaily) => {
let isValid = this.isFormValid();
this.setState({ timesDaily: timesDaily, validity: isValid });
}
setPrescriber = (prescriber) => {
this.setState({ prescriber: prescriber });
}
setDiagnoses = (diagnoses) => {
this.setState({ forDiagnoses: diagnoses });
}
setInstructions = (instructions) => {
this.setState({ instructions: instructions });
}
isFormValid = () => {
return (this.state.name !== '' && (this.state.dosage !== '' && this.state.dosage > 0)
&& (this.state.timesDaily !== '' && this.state.timesDaily > 0));
}
render() {
return (
<View style={styles.container}>
<Text style={{color: 'red', marginBottom: 5, marginLeft: -125}}>* denotes required field</Text>
<View style={{flexDirection: 'row'}}>
<Text style={styles.required}>*</Text>
<TextInput
style={styles.inputText}
onChangeText={(name) => this.setName(name)}
placeholder="Medication Name"
value={this.state.name}
/>
</View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.required}>*</Text>
<TextInput
style={styles.inputText}
onChangeText={(dosage) => this.setDosage(dosage)}
placeholder="Dosage"
value={this.state.dosage}
/>
</View>
<View style={styles.dosageContainer}>
<Text style={{flex: 1, marginTop: 100, marginLeft: 30}}>
Select Measurement:
</Text>
<Picker
style={styles.picker}
selectedValue={this.state.selectedMeasurement}
onValueChange={(itemValue, itemIndex) =>
this.setMeasurement(itemValue)
}>
<Picker.Item label="mg" value="mg" />
<Picker.Item label="g" value="g" />
<Picker.Item label="ml" value="ml" />
</Picker>
</View>
<View style={{flexDirection: 'row'}}>
<Text style={styles.required}>*</Text>
<TextInput
style={styles.inputText}
onChangeText={(timesDaily) => this.setTimesDaily(timesDaily)}
placeholder="Times daily"
value={this.state.timesDaily}
/>
</View>
<TextInput
style={styles.inputText}
onChangeText={(prescriber) => this.setPrescriber(prescriber)}
placeholder="Prescriber"
value={this.state.prescriber}
/>
<TextInput
style={styles.inputText}
onChangeText={(diagnoses) => this.setDiagnoses(diagnoses)}
placeholder="For diagnoses"
value={this.state.forDiagnoses}
/>
<TextInput
style={styles.inputText}
onChangeText={(instructions) => this.setInstructions(instructions)}
placeholder="Instructions"
value={this.state.instructions}
/>
<TouchableOpacity
style={this.isFormValid() ? styles.validButton : styles.invalidButton}
disabled={!Boolean(this.state.name && this.state.dosage && this.state.timesDaily)}
onPress={() => {
this.props.navigation.goBack()
this.props.addMedication(this.state.name, this.state.dosage,
this.state.selectedMeasurement, this.state.timesDaily)
}}
>
<Text style={{color: 'white'}}>Add Medication</Text>
</TouchableOpacity>
</View>
)
}
}
You can pass the state value but I think you cannot pass the addMedication method just like this.
Could you please try passing an arrow function that uses the setState method?
For example:
<Stack.Screen name="Add New Medication">
{(props) => <AddMedication {...props} addMedication={(name, dosage, measurement, timesDaily)=> {this.addMedication(name, dosage, measurement, timesDaily)}} />}
</Stack.Screen>

Adding item to Flatlist by getParam

DIET (MAIN PAGE)
export class Diet extends Component {
constructor(props) {
super(props);
this.state = {
foodList: [],
};
}
render() {
return (
<View style={{ flex: 1, top: hp("12%"), height: hp("100%") }}>
<Button onPress={()=> this.props.navigation.navigate('FoodCreate')}>
<Text>Press to insert Food Name</Text>
</Button>
<FlatList
data={{this.props.route?.params?.foodList}
keyExtractor={(item, index) => item.key.toString()}
renderItem={(data) => (
<ListItem itemDivider title={data.item.food} />
)}
/>
</View>
FOODCREATE
export class FoodCreate extends Component {
constructor(props) {
super(props);
this.state = {
food: null,
foodList: [],
};
}
submitFood = (food) => {
this.setState({
foodList: [
...this.state.foodList,
{
key: Math.random(),
name: food,
},
],
});
this.props.navigation.navigate("Diet", {
foodList: this.state.foodList,
});
};
render() {
return (
<Container>
<Header>
<Left>
<Button transparent>
<Icon
name="arrow-back"
onPress={() => this.props.navigation.goBack()}
style={{ fontSize: 25, color: "red" }}
/>
</Button>
</Left>
<Body>
<Title>Add Food</Title>
</Body>
<Right>
<Button transparent>
<Icon
name="checkmark"
style={{ fontSize: 25, color: "red" }}
onPress={() => {
this.submitFood(this.state.food);<-----------
}}
/>
</Button>
</Right>
</Header>
<View style={{ alignItems: "center", top: hp("3%") }}>
<TextInput
placeholder="Food Name"
placeholderTextColor="white"
style={styles.inptFood}
value={this.state.food}
onChangeText={(food) => this.setState({ food })}
/>
</View>
Hey everyone, so this is how this app should work: when I start Expo it brings me to the Diet screen, from there I press the Button to add a new food to the Flatlist, once I get sent to FoodCreate screen I type in the TextInput the name of the food and when I click the checkmark in the header it should send me back to Diet and display in the Flatlist the name of the food I typed, and so on. When I run the app it gives me the following error: this.props.navigation.getParam is not a function
You have to use
this.props.route.params.foodList
The parameters are passed via the route.params prop, with Navigation v5 the getParams option is not there

React-Native Big Problems with Confirming Password

i got a Questions because I am new in React native! I was trying to find an Answer that fits with my Code. But nothing is working well! Im overloaded. Maybe some of u guys can help me with my problem!
So i need a "simple" confirming password message if someone is writing the two fields wrong because there is no match!
import React, { Component } from 'react';
import {View, Image, TextInput} from 'react-native';
import { Container, Header, Content, Button, Icon, Body, Left, Right,
Text, Title, Card, CardItem } from 'native-base';
import styles from '../Style/Style.js'
import Foect from 'foect';
import IconNew from 'react-native-vector-icons/MaterialIcons';
export default class AnmeldeScreen extends Component {
constructor(props) {
super(props);
this.state = {
icEye: 'visibility-off',
password: true,
}
}
static navigationOptions = {
header: null
}
changePwdType = () => {
let newState;
if (this.state.password) {
newState = {
icEye: 'visibility',
password: false
}
} else {
newState = {
icEye: 'visibility-off',
password: true
}
}
// set new state value
this.setState(newState)
};
render () {
var {navigate} = this.props.navigation;
return (
<Container>
{/*---------------------------------------------------- H E A D E R ------------------------------------------------------------*/}
<Header>
<Left>
<Button transparent onPress={() => navigate("Start", {})}>
<Icon name="arrow-back" />
</Button>
</Left>
<Body>
<Title style={styles.titelintervall}>Registrieren</Title>
</Body>
<Right>
</Right>
</Header>
{/*---------------------------------------------------- C O N T E N T ------------------------------------------------------------*/}
<Content padder>
<Image source={require('../images/low-carb-camp-logo-breit.png')} style={styles.secondimagelogo} />
<Foect.Form
defaultValue={{
email: ''
}}
onValidSubmit={model => {
console.log(model);
}}
>
{ /* you can use form for triggering submit or checking form state(form.isSubmitted, form.isValid, ...) */ }
{ form => (
<View>
{ /* every Foect.Control must have a name and optionally validation rules */ }
<Foect.Control name="fullName" required minLength={2} maxLength={32}>
{ /* you can use control for getting/setting it's value, checking/updating(control.isValid, control.markAsTouched(), ...) it's state, checking it's errors(control.errors.required) */ }
{ control => (
<View>
<Text style={{ marginTop: 10, color: '#8BC051' }}>Dein Name</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderBottomWidth: 1}}
/* mark control as touched on blur */
onBlur={control.markAsTouched}
/* update control's value */
onChangeText={(text) => control.onChange(text)}
/* get control's value */
value={control.value}
placeholder="Hier vollständigen Namen eingeben"
/>
{ /* check control state and show error if necessary */ }
{ control.isTouched &&
control.isInvalid &&
<Text style={{ color: 'red' }}>Bitte trage deinen Namen ein.</Text> }
</View>
) }
</Foect.Control>
<Foect.Control name="email" required email>
{ control => (
<View>
<Text style={{ marginTop: 10, color: '#8BC051' }}>Email</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderBottomWidth: 1}}
keyboardType="email-address"
onBlur={control.markAsTouched}
onChangeText={(text) => control.onChange(text)}
value={control.value}
placeholder="Hier E-Mail eingeben"
/>
{ control.isTouched &&
control.isInvalid &&
<View>
<Text style={{ color: 'red'}}>{control.value} ist keine gültige E-Mail</Text>
</View> }
</View>
) }
</Foect.Control>
<Foect.Control name="password" required pattern={/(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/}>
{ control => (
<View>
<Text style={{ marginTop: 10, color: '#8BC051' }}>Passwort
</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderBottomWidth: 1}}
secureTextEntry={true}
onBlur={control.markAsTouched}
onChangeText={(text) => control.onChange(text)}
value={control.value}
secureTextEntry={this.state.password}
placeholder="Passwort erstellen"
/>
<IconNew style={styles.icon}
name={this.state.icEye}
size={25}
color={this.props.iconColor}
onPress={this.changePwdType}
/>
{ control.isTouched &&
control.isInvalid &&
<View>
{ control.errors.pattern ?
<Text style={{ color: 'red' }}>Dein Passwort muss mindestens 8 Zeichen lang sein und mindestens ein Sonderzeichen oder eine Zahl enthalten.</Text> :
<Text style={{ color: 'red' }}>Bitte trage dein Passwort ein.</Text> }
</View> }
</View>
) }
</Foect.Control>
<Foect.Control name="confirmpassword">
{ control => (
<View>
<Text style={{ marginTop: 10, color: '#8BC051' }}>Passwort wiederholen
</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderBottomWidth: 1}}
secureTextEntry={true}
onBlur={control.markAsTouched}
onChangeText={(text) => control.onChange(text)}
value={control.value}
placeholder="Passwort bitte wiederholen"
/>
</View>
) }
</Foect.Control>
</View>
) }
</Foect.Form>
<View style={{marginTop: 10}}>
<Button full warning style={styles.buttonintervall} onPress={
() => navigate("Ziel", {})}>>>
<Text>Registrieren</Text>
</Button>
</View>
<Text style={styles.secondtextfb}> oder </Text>
<Card>
<CardItem>
<Icon name="logo-facebook" style={{color: '#234c6e'}} />
<Text>Über Facebook registrieren</Text>
<Right>
<Icon name="arrow-forward" />
</Right>
</CardItem>
</Card>
</Content>
</Container>
);
}
}

React Native Expandable View Issue

This is my component usage
<Panel title="ABC Trade & Investments (Pvt) LTd" amount="$,350.00 LKR">
<View style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<TextInput style={styles.textBox} />
</View>
<View style={styles.container}>
<TouchableHighlight
style={styles.buttonContainerOK}
onPress={this.onPressLearnMore}
underlayColor="#a7ccaf"
>
<Image
style={styles.buttonImage}
source={require("./assets/img/ic_done_24px.png")}
/>
</TouchableHighlight>
<View style={styles.space} />
<TouchableHighlight
style={styles.buttonContainerDelete}
onPress={this.onPressLearnMore}
underlayColor="#f79191"
>
<Image
style={styles.buttonImage}
source={require("./assets/img/ic_clear_24px.png")}
/>
</TouchableHighlight>
</View>
</View>
</Panel>
Here I add my component code
class Panel extends Component {
constructor(props) {
super(props);
this.icons = {
up: require("../assets/img/Arrowhead-01-128.png"),
down: require("../assets/img/Arrowhead-Down-01-128.png")
};
this.state = {
title: props.title,
expanded: false,
animation: new Animated.Value()
};
}
onPressLearnMore() {
console.log("Test");
}
componentWillMount() {
console.log("this.state.expanded => " + this.state.expanded);
console.log("this.state.maxHeight => " + this.state.maxHeight);
console.log("this.state.minHeight => " + this.state.minHeight);
}
toggle() {
let initialValue = this.state.expanded
? this.state.maxHeight + this.state.minHeight
: this.state.minHeight,
finalValue = this.state.expanded
? this.state.minHeight
: this.state.maxHeight + this.state.minHeight;
this.setState({
expanded: !this.state.expanded
});
console.log("initialValue => " + initialValue);
this.state.animation.setValue(initialValue);
Animated.spring(this.state.animation, {
toValue: finalValue
}).start();
console.log("finalValue => " + finalValue);
}
_setMaxHeight(event) {
if (!this.state.maxHeight) {
console.log("_setMaxHeight => " + event.nativeEvent.layout.height);
this.setState({
maxHeight: event.nativeEvent.layout.height
});
}
}
_setMinHeight(event) {
if (!this.state.minHeight) {
console.log("_setMinHeight ! => " + event.nativeEvent.layout.height);
this.setState({
minHeight: event.nativeEvent.layout.height,
animation: new Animated.Value(event.nativeEvent.layout.height)
});
}
}
render() {
let icon = this.icons["down"];
if (this.state.expanded) {
icon = this.icons["up"];
}
return (
<Animated.View
style={[styles.container, { height: this.state.animation }]}
>
<View
style={styles.titleContainer}
onLayout={this._setMinHeight.bind(this)}
>
<View style={styles.header}>
<Text style={styles.title}>{this.state.title}</Text>
<Text style={styles.amount}>4,350.00 LKR</Text>
</View>
<TouchableHighlight
style={styles.toggle_button}
onPress={this.toggle.bind(this)}
underlayColor="#f1f1f1"
>
<Image style={styles.buttonImage} source={icon} />
</TouchableHighlight>
<TouchableHighlight
style={styles.approve_button}
onPress={this.onPressLearnMore}
underlayColor="#a7ccaf"
>
<Image
style={styles.listButtonImage}
source={require("../assets/img/ic_done_24px.png")}
/>
</TouchableHighlight>
<View style={styles.space} />
<TouchableHighlight
style={styles.reject_button}
onPress={this.onPressLearnMore}
underlayColor="#f79191"
>
<Image
style={styles.listButtonImage}
source={require("../assets/img/ic_clear_24px.png")}
/>
</TouchableHighlight>
</View>
<View style={styles.body} onLayout={this._setMaxHeight.bind(this)}>
{this.props.children}
</View>
</Animated.View>
);
}
}
Issue is that I have added TextInput to expanded Panel.But once I clicked it my view is collapsed.here I will attached image of my two scenarios.
It seems issue occur due to onLayout={this._setMaxHeight.bind(this)} this code.But I could not resolve that.Please help me.
FYI - this is the link I refer to build this - https://moduscreate.com/blog/expanding-and-collapsing-elements-using-animations-in-react-native/
It seems that, nested event bubbling took place here. You can avoid this by adding onFocus and onKeyPress events to yout TextInput and need to handle parent event as follows:
<TextInput
onFocus={this.restrictParentClick.bind(this)}
onKeyPress={this.restrictParentClick.bind(this)}
/>
And this will be your restrictParentClick function as follows:
restrictParentClick (evnt) {
evnt.preventDefault()
evnt.stopPropagation();
if(evnt.nativeEvent)
evnt.nativeEvent.stopImmediatePropagation();
}
}

How to find if users exist in Firebase?

I am using Firebase Web SDK and know methods to check whether a child in a collection exists or not. However I can't find a concise example checking the existence of a user, without trying to sign him/her in.
export class Email extends Component {
constructor (props) {
super(props)
this.state = { email: '' }
}
checkEmail () {
const { email } = this.state
FirebaseApp.auth()
.createUserWithEmailAndPassword(email, uuid.v4())
.then((User) => Actions.Password({ User }))
.catch((error) => {
// Handle Errors here.
console.log('firebase', {error})
this.setState({error})
// ...
})
// Actions.password()
}
render () {
return (
<View style={{ ...styles.onboarding, backgroundColor: 'purple' }}>
<View style={{ borderBottomWidth: 3, borderColor: 'black', padding: 10 }}>
<TextInput ref='email'
style={styles.input}
keyboardType='email-address'
placeholder='Your email'
value={this.state.email}
onChangeText={(email) => this.setState({email: email.toLowerCase()})} />
</View>
{!this.state.error ? null
: <Text>
{this.state.error.message}
</Text>
}
<TouchableOpacity onPress={() => this.checkEmail()} style={{ ...styles.button, margin: 20, borderColor: 'black' }}>
<Text style={styles.buttonText}>Next</Text>
</TouchableOpacity>
</View>
)
}
}
Do you have any piece of code we could reuse?
For the moment, and because it complies with my app security policy and setup, I created an email collection indexed precisely by ids.
firebase.ref(`emails/${user.email}`).set(true)

Resources