React Native 5.x passing parameter working example - javascript

I'm studying react native version 5 and I would need a short but working example of two files.js, for example App.js and Receiver.js where:
in App.js you can insert a text through Text Input
in Receiver.js it receives and shows the text inserted once have been passed as state and parameter by the previous page.
Can anyone help me?

App.js
export default class App extends Component {
state = {
username: 'demo'
};
render() {
return (
<Text style={Style.label}>User Name</Text>
<TextInput
style={Style.input}
placeholder="UserName"
onChangeText={(value) => this.setState({username: value})}
value={this.state.username}
/>
<Button
title="LOGIN"
onPress={() => this.props.navigation.navigate("Receiver", {username: this.state.username}) }
/>
);
}
}
Receiver.js
export default class Receiver extends Component {
render() {
const { username} = this.props.route.params;
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>User Name: {username}</Text>
</View>
);
}
}

A small suggestion: Read the official document before beginning.✌️
https://reactnavigation.org/docs/params/

Related

How to pass dynamic data between two screen in React native?

I have referred official documentation of react native(https://reactnavigation.org/docs/params).In that I observed that they are passing the static data between screens. But I want to pass data taken from user.
If someone knows how to share data then please help. I have taken help of context api also but I failed to pass the data. Any source or material will also be helpful.
Your issue may be related to your input. It seems you are not capturing your inputs into a state variable.
Check this example from ReactNative input:
https://reactnative.dev/docs/0.65/textinput
import React from "react";
import { SafeAreaView, StyleSheet, TextInput } from "react-native";
const Screen1 = () => {
const [text, onChangeText] = React.useState("Hello world");
return (
<SafeAreaView>
<TextInput
style={styles.input}
onChangeText={onChangeText}
value={text}
/>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
},
});
export default Screen1;
Then you could use navigate:
navigation.navigate('Details', {
param1: text,
});
In the other screen you could read the param1 like this:
route.params.param1
Don't forget
Don't forget to pass route as a parameter in fuction( {route) }{ ... }
Checkout this code snippet.
React.useEffect(() => {
if (route.params?.post) {
// Post updated, do something with `route.params.post`
// For example, send the post to the server
}
}, [route.params?.post]);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Create post"
onPress={() => navigation.navigate('CreatePost')}
/>
<Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>
</View>
);
}
function CreatePostScreen({ navigation, route }) {
const [postText, setPostText] = React.useState('');
return (
<>
<TextInput
multiline
placeholder="What's on your mind?"
style={{ height: 200, padding: 10, backgroundColor: 'white' }}
value={postText}
onChangeText={setPostText}
/>
<Button
title="Done"
onPress={() => {
// Pass and merge params back to home screen
navigation.navigate({
name: 'Home',
params: { post: postText },
merge: true,
});
}}
/>
</>
);
}
to pass a param to a screen
navigation.navigate('screenName', {
paramName: 'valueYouwantToPass',
});
because you mentioned context API, try
Async Storage
import {AsyncStorage} from 'react-native';
or
Device Event Emitter
import { DeviceEventEmitter} from 'react-native';

Get value from a TextInput component in react native

Dynamically generate a TextInput when you press a button but I can’t get the value that the user digits,try to use states but I can’t because it’s not with the other general textInputs but it’s imported as Field.
try to create a state in the component file and move it to the general view and print it to see if it works and not...is there any way to bring this state?
general view:
import Campo from './campoInput';
constructor(props){
super(props);
this.state={
Cbusto:"",
Ccintura:"",
Ccadera:"",
valueArray: []
};
this.addNewEle = false;
}
agregarCampo=()=>{
this.addNewEle = true;
const newlyAddedValue = { text: 'prueba'};
this.setState({
valueArray: [...this.state.valueArray, newlyAddedValue]
});
}
render(){
return(
------Here are the normal textInput-----
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele} />;
})}
</View>
<View style={styles.flex}>
<View style={styles.ButtonAdd}>
<Button
title="Add input"
color="#B13682"
onPress={this.agregarCampo}
></Button>
</View>
)
}
Component:
constructor(props){
super(props);
this.state={
info:""
};
}
render(){
return(
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={(text) => this.setState({info:text})}></TextInput>
</View>
</View>
)
}
can be solved by adding the onChangeText event to the Field component in the overview and in the same way in the TextInput of the component being imported, using props status
General view:
<View style={{ flex: 1, padding: 4 }}>
{this.state.valueArray.map((ele) => {
return <Campo item={ele}
onChangeText={(text) => this.setState({ info: text })}
/>;
})}
</View>
Component
<View>
<Text>pruba:{this.props.item.text}</Text>
<View style={styles.input}>
<TextInput onChangeText={this.props.onChangeText}></TextInput>
</View>
</View>

Update page data

I need your help. I have a problem with updating data on a page. Basically I have a homepage where there is data like "FirstName: ...", "LastName: ..." which are retrieved from the login.
Once the login has been completed, you will automatically be taken to the Homepage page each time the app is started.
In this way I retrieve the information on the Homepage page.
The problem is that the user can modify this data through a form (ModifyProfile), and once the data is done they are not updated.
How can I update them anyway?
Thank you.
Homepage.js
class HomepageUtente extends Component {
constructor(props) {
super(props);
this.state = {
}
}
render() {
const FirstName = global.utente.data.Person.FirstName;
const LastName = global.utente.data.Person.LastName;
return (
<View style={style.container}>
<View style={style.page}>
<Icon name="user-circle" color="#64c7c0" size={70} onPress={() => Actions.yourprofile({ cf: Username } )} />
<Text
style={{ textAlign: 'center', fontSize: 20, }}>{"Welcome"}
</Text>
<Text style={{ textAlign: 'center', fontSize: 20, color: '#64c7c0', fontWeight: 'bold' }}>
{FirstName} {LastName}
</Text>
<Text style={{ color: '#64c7c0', paddingTop: 20 }} onPress={() => Actions.ModifyProfile({ cf: Username })} >Modify Profile</Text>}
</View>
</View>
)
}
}
ModifyProfile
export default class ModificaProfilo extends Component {
constructor(props) {
super(props);
this.state = {};
}
findUtente(cf) {
//Search data cf in the db
//......
//......
.then(response => {
let utente = response.docs[0];
console.log("Utente: " + utente)
console.log("Sei qui 1")
utente.Person.FirstName = this.state.FirstName;
utente.Person.LastName = this.state.LastName;
global.utente.db.localdb().put(utente);
})
.catch(function(err) {
console.log(JSON.stringify(err));
})
}
render() {
return (
<View style={style.container}>
<View style={style.page}>
<KeyboardAwareScrollView>
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="Name"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={FirstName =>
this.setState({ FirstName })
}
/>
</View>
<View style={style.inputContainer}>
<TextInput
style={style.inputs}
placeholder="Surname"
placeholderTextColor="#64c7c0"
keyboardType="default"
underlineColorAndroid="grey"
onChangeText={LastName =>
this.setState({ LastName })}
/>
</View>
<View style={style.footer}>
<TouchableOpacity
style={[style.button, style.buttonOK]}
onPress={() => this.findUtente(this.props.cf)}
>
<Text style={style.buttonTesto}>Modifica</Text>
</TouchableOpacity>
</View>
Actually, you can do that but you shouldn't. Let's solve it first.
The component in Homepage.js, we call it A ;
The component in ModifyProfile, we call it B ;
You need a reference to component A, and then call A.forceUpdate().
It means you add global.A = this in Homepage.js;
add global.A.forceUpdate() in ModifyProfile after you get the new data;
Why: React Component would reRender only if the state or props of the component changes, that's why you need to call forceUpdate to make component A reRender again unconditionally.
if your change the FirstName by global.utente.data.Person.FirstName = 'NewName', component A can not detect the change event.
By the way, you should use a state container like redux to help you, rather than a global variable. You can connect FirstName as your props.
I recommend dvajs which is easy to learn, you can just focus on the data and flow, you don't need to care about if a component should update most of the times.
And there is a starter of dvajs, you can just run it quickly followed by:
react-native-dva-starter
Forget it if I misunderstood your question.

How do I let a screen know other screen's state

Now I am trying to let a screen containing some lists know other screen's state.
The main screen contains some Form Components which user can input text to.
Other screens, Form Components contain some TextInput forms.
If a user inputs some texts into some form and then if this user puts a back button or a save-button, I want to change the main screen's state of these form components to be like "Editing", "Not Edit" or "Complete".
How to change the state of each form component's state on the Main screen?
This picture is the main screen. Please focus on Red characters. There will be changed if a user will input some text into a form on other screens.
This is a input-screen
handleOnpress() {
const db = firebase.firestore();
const { currentUser } = firebase.auth();
db.collection(`users/${currentUser.uid}/form1`).add({
form1 : [
{ fullname: this.state.fullname },
{ middleName: this.state.middleName },
{ reason: this.state.reason },
{ birthPlaceCity: this.state.birthPlaceCity },
{ birthPlaceCountry: this.state.birthPlaceCountry },
{ Citizinchip: this.state.Citizinchip },
{ aboutMaridge: this.state.aboutMaridge },
{ fromTermOfMaridge: this.state.fromTermOfMaridge },
{ ToTermOfMaridge: this.state.ToTermOfMaridge },
{ nameOfSpouse: this.state.nameOfSpouse },
{ birthdateOfSpouse: this.state.birthdateOfSpouse },
{ fromTermOfExMaridge: this.state.fromTermOfExMaridge },
{ ToTermOfExMaridge: this.state.ToTermOfExMaridge },
{ nameOfExSpouse: this.state.nameOfExSpouse },
{ birthdateOfExSpouse: this.state.birthdateOfExSpouse }]
})
.then(() => {
this.props.navigation.goBack();
})
.catch((error) => {
console.log(error);
});
}
render() {
return (
<ScrollView style={styles.container}>
<InfoHeader navigation={this.props.navigation}>申請者情報1
</InfoHeader>
<Notes />
<QuestionTextSet onChangeText={(text) => { this.setState({
fullname: text }); }} placeholder={'例:留学太郎'}>姓名(漢字表記)
</QuestionTextSet>
<QuestionTextSet onChangeText={(text) => { this.setState({
middleName: text }); }}>本名以外に旧姓・通称名(通名)・別名など他の名前が
あればローマ字で記入</QuestionTextSet>
<QuestionTextSet onChangeText={(text) => { this.setState({
reason: text }); }} placeholder={'例:結婚・離婚/ご両親の離婚のためな
ど'}>別名がある方はその理由</QuestionTextSet>
<SubmitButton style={styles.saveButton} onPress=
{this.handleOnpress.bind(this)}>保存</SubmitButton>
<Copyrights />
</ScrollView>
);
This is the main screen.
class WHApply extends React.Component {
render() {
return (
<ScrollView style={styles.container}>
<WHApplyBar navigation={this.props.navigation} />
<WHApplyIndexBar />
<HWApplyMailBar />
<HWApplyList navigation={this.props.navigation} />
<Agreement />
<SubmitButton>同意して送信</SubmitButton>
<Logout />
<Copyrights />
</ScrollView>
);
}
}
And this is a code of HWApplyList.
This component is import to the main screen.
class HWApplyList extends React.Component {
state = {
fontLoaded: false,
}
async componentWillMount() {
await Font.loadAsync({
FontAwesome: fontAwesome,
});
this.setState({ fontLoaded: true });
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={() => {
this.props.navigation.navigate('PersonalInfo1'); }} >
<View style={styles.listBox}>
<Text style={styles.listBoxText}>
申請者情報1
</Text>
<View style={styles.inputBotton}>
<Text style={styles.inputBottonText}>未入力</Text>
</View>
<View style={{ flex: 1, justifyContent: 'center' }}>
{
this.state.fontLoaded ? (
<View style={styles.navigationButton}>
<Text style={styles.navigationButtonIcon}>{'\uf0da'}
</Text>
</View>
) : null
}
</View>
</View>
</TouchableOpacity>
In addition to the previous answer, you will also need to pass a handler function to the screen child. This handle function will allow your child screen to modify the parent's state.
Something like
onChange(value) {
this.setState({value});
}
render() {
return (
<Screen1 value={this.state.value} onChange={this.onChange}/>
<Screen2 value={this.state.value}/>
)
}
When you start to make many components that uses each other's state, Using a tool like "redux" makes it much easier.
Instead of putting your data ( that's you want it to be shared with the other components ) in a particular component state. you can create a common state for the whole app and you can access this state from any component.
here's a good article:
Understanding Redux: The World’s Easiest Guide to Beginning Redux

Text Input not showing up in iOS simulator

I'm a newbie to React-Native, so I've been going through a tutorial to create a login screen. The code in the tutorial is out of date. I'm creating a login screen made up of a few components. However, a certain TextInput isn't showing up in the simulator. Here's the parent component "LoginForm" from LoginForm1.js:
export default class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
}
render() {
return (
<Card>
<CardSection>
<Input
placeholder="user#gmail.com"
label="Email"
value={this.state.email}
onChangeText={text => this.setState({ text })}
/>
</CardSection>
The child component "Input" is wrapped in components "CardSection" and "Card" (these pass their props with a View displaying {this.props.children}, but here's the "Input" component from Input.js:
export default class Input extends Component {
render() {
return (
<View style={styles.containerStyle}>
<Text style={styles.labelStyle}>{this.props.label}</Text>
<TextInput
placeholder={this.props.placeholder}
autoCorrect={false}
style={styles.inputStyle}
value={this.props.value}
onChangeText={this.props.onChangeText}
/>
</View>
);
}
}
const styles = StyleSheet.create({
inputStlye: {
color: '#000',
paddingRight: 5,
paddingLeft: 5,
fontSize: 18,
Height: 50,
Width: 50,
flex: 2,
},
This code doesn't throw any errors, but the TextInput from "Input" doesn't show up. I've given it some dimensions in the styling, so that can't be it. If I replace the TextInput with just normal Text, then the contents of that Text tag will appear in the simulator. Am I missing something to do with passing props? Any help would be much appreciated, thank you!
You have the value being passed down as value={this.state.email}, but you're onChangeText is updating this.state.text so just change it to value={this.state.text}.

Categories