In a a react native app I have some text and then a textinput rendered on the screen. I'm trying to figure out how to output the same text and the same textinput when I submit on in the original text field. I was thinking to do this recursively but I'm not sure how where and how implement the function to do so.
If it's in the same screen, than you can use local state. here's the example
class TestScreen extends Component {
constructor(props) {
super(props)
this. state = {
firstInput:'First Input',
secondInput:''
}
this.submit = this.submit.bind(this)
}
submit(){
this.setState({ secondInput: this.state.firstInput })
}
render() {
return (
<View style={{flex:1,marginTop:40}}>
<View>
<Text>Text Input #1</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
onChangeText={(text)=> this.setState({firstText:text})}
value={this.state.firstInput}
/>
<Button
onPress={this.submit}
title="Submit"
/>
</View>
<View style={{marginTop:20}}>
<Text>Text Input #1</Text>
<TextInput
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
value={this.state.secondInput}
/>
</View>
</View>
);
}
}
I hope that help. Thanks
Perhap you can use ref,state,conditional rendering. let's code talk
const MyInputs = (props) => {
inputs =props.inputs
result=inputs.map(function(value,index){
return(
<TextInput key={index} style={styles.input} value={value} />
)
})
return(
<View>
{result}
</View>
)
}
class TestScreen extends Component {
constructor(props) {
super(props)
this. state = {
inputs:[]
}
this.submit = this.submit.bind(this)
this.clearText = this.clearText.bind(this)
}
submit(){
let lastInput=this._textInput._lastNativeText
let inputs=this.state.inputs
this._textInput.setNativeProps({text: ''});
inputs.push(lastInput)
this.setState({
inputs:inputs
})
}
clearText = () => {
this.setState({
inputCount: this.state.inputCount + 1,
})
this._textInput.setNativeProps({text: ''});
}
render() {
return (
<View style={{flex:1,marginTop:40}}>
<View>
<Text>Text Input #1</Text>
<TextInput
style={styles.input}
ref={component => this._textInput = component}
/>
<Button onPress={this.submit} title="Submit"
/>
</View>
<MyInputs inputs={this.state.inputs}/>
</View>
);
}
}
Related
I am trying to call my emailInput and have it show up on my createPassword page, specifically where youremail#email.com is. I have given the two pages below, the email page consisting of a user input and the password page where I want that user input to appear on. I cannot really wrap my head around how to refer to the Input in my onPress. Any insight at all is appreciated more than you know!
Also, can I call two onPress's like that? Or do I need to create two functions and do it that way?
SignUpEmail.js
export default class SignUpEmailPage extends Component {
constructor() {
super();
this.state = {
color1: '#A2A2A2'};}
render() {
return (
<View style={styles.containerMain}>
{/* Email Input */}
<Container style = {styles.emailInput}>
<Form>
<Item floatingLabel >
<Label style={{color:this.state.color1}}>Email Address</Label>
<Input
style={styles.textInput}
autoCorrect={false}
autoCapitalize="none"
onFocus={() => this.setState({color1: '#F7018D'})}
onBlur={() => this.setState({color1: '#A2A2A2'})}
/>
</Item>
</Form>
</Container>
<View style={styles.containerBottom}>
<ContinueButton
onPress = {() => navigation.navigate('CreatePassword', { emailInput: })}
onPress={() => this.props.navigation.navigate('CreatePassword')}
/>
</View>
CreatePassword.js
export default class CreatePasswordPage extends Component {
constructor() {
super();
this.state = {
color1: '#A2A2A2'};}
render() {
return (
<View style={styles.containerMain}>
{/* Password Input */}
<Container style = {styles.passwordInput}>
<Form>
<Item floatingLabel>
<Label style={{color:this.state.color1}}>Password</Label>
<Input
style={styles.textInput}
autoCorrect={false}
autoCapitalize="none"
secureTextEntry={true}
onFocus={() => this.setState({color1: '#F7018D'})}
onBlur={() => this.setState({color1: '#A2A2A2'})}
/>
</Item>
</Form>
</Container>
<View style={styles.containerHeader}>
<Text style={styles.title}>Create a Password</Text>
</View>
<View style={styles.containerCaption}>
<Text style={styles.caption}> Lets create your Password for
</Text>
</View>
<View style={styles.containerCaption2}>
<Text style={styles.caption}> youremail#email.com</Text>
</View>
<View style= {styles.backArrowPlacement}>
<BackArrow
onPress={() => this.props.navigation.navigate('SignUpEmail')}
/>
</View>
<View style={styles.containerBottom}>
<ContinueButton
onPress={() => this.props.navigation.navigate('PhoneVerification')}
/>
</View>
</View>
);
}
}
You can't use navigation.navigate as it needs Hooks implementation in the functional component. You can do is
export default class SignUpEmailPage extends Component {
constructor() {
super();
this.state = {
color1: '#A2A2A2',
inputValue: '', // add state here
};
}
updateInputValue = (evt) => {
this.setState({
inputValue: evt.target.value
});
}
render() {
return (
<Input
value = {this.state.inputValue}
onChange={this.updateInputValue }
/>
<ContinueButton
//onPress = {() => navigation.navigate('CreatePassword', { emailInput: })} // remove this
onPress={() => this.props.navigation.navigate('CreatePassword',{ emailInput: this.state.inputValue })} // use this like
/>
)
}
}
Currently, this - is how the SearchBar and FlatList is showing up on the screen. Upon clicking on the SearchBar and typing one of the list components, it shows up this- way. I want the FlatList to only appear when I click on the SearchBar. How do I implement this in the app? Something like a dropdown search bar...
import React from 'react';
import { View, Text, FlatList, ActivityIndicator, StyleSheet } from 'react-native';
import { SearchBar } from 'react-native-elements';
import { Button, Menu, Divider, Provider, TextInput } from 'react-native-paper';
const restaurantList = [
{
type: 'Italian',
name: 'DiMaggio'
},
{
type: 'Greek',
name: 'Athena'
}
];
export default class App extends React.Component {
static navigationOptions = {
title: 'Search for Restaurants'
};
constructor (props) {
super(props);
this.state = {
loading: false,
data: restaurantList,
error: null,
value: '',
};
this.arrayholder = [];
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '86%',
backgroundColor: '#CED0CE',
marginLeft: '14%'
}}
/>
);
};
searchFilterFunction = text => {
this.setState({
value: text
});
const newData = restaurantList.filter(item => {
console.log(item.type)
const itemData = `${item.name.toUpperCase()} ${item.type.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.includes(textData);
});
this.setState({
data: newData
});
};
renderHeader = () => {
return (
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
/>
);
};
render () {
if (this.state.loading) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<ActivityIndicator />
</View>
);
} else {
return (
<Provider>
<View
style={{
paddingTop: 50,
flexDirection: 'row',
justifyContent: 'center',
}}>
<View style={styles.container}>
<FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state}
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
</View>
</View>
<View style={styles.container}>
<TextInput />
</View>
</Provider>
);
}
}
}
Try this way
this.state = {
searchClicked: false
};
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
onFocus={() => this.setState({searchClicked: true})}
onBlur={() => this.setState({searchClicked: false})}
/>
<View>{this.renderHeader()}</View>
{this.state.searchClicked && <FlatList
keyExtractor={(item, index) => `${index}`}
extraData={this.state}
data={this.state.data}
renderItem={({ item }) => (
<Text>{item.name} {item.type}</Text>
)}
ItemSeparatorComponent={this.renderSeparator}
// ListHeaderComponent={this.renderHeader} <—- Remove from here —->
/>}
In case #Lakhani reply doesn't satisfy your question, I have another suggestion for you.
Your SearchBar should contain a TextInput. You can use onFocus and onBlur props to capture event you click on SearchBar or leave it.
...
<SearchBar
placeholder="Type..."
value={this.state.value}
onChangeText={text => this.searchFilterFunction(text)}
onFocus={()=>this.setState({showList: true})} // <---
onBlur={()=>this.setState({showList: false})} // <---
/>
...
render() {
return (
...
{
this.state.showList && <FlatList ... />
}
)
}
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>
When I want to distribute my data from my firebase database to my React Native mobile application in the form of a carousel with SwiperFlatList, an error is displayed
each time my class is updated, showing me as follows: "Invariant violation: scrolltoindex out of range: requested Nan but maximum is 1."
By hiding the error the carousel works well but it can be very annoying and cause problems during its build.
Here are my codes:
My Render function :
renderPost=post=>{
return(
<View style={styles.card}>
<HorizontalCard title={post.title_new} desc={post.text} img={post.image} />
</View>
)
}
HorizontalCard Component :
export default class HorizontalCard extends Component {
constructor(props) {
super(props);
}
static propTypes = {
screen: PropTypes.string,
title: PropTypes.string,
desc: PropTypes.string,
img: PropTypes.string,
};
state = {
modalVisible: false,
};
setModalVisible(visible) {
this.setState({modalVisible: visible});
}
render() {
return (
<View style={{flex: 1}}>
<TouchableOpacity
onPress={() => {
this.setModalVisible(true);
}}
style={styles.container}>
<Modal
animationType="slide"
transparent={false}
visible={this.state.modalVisible}
onRequestClose={() => {
alert('Modal has been closed.');
}}>
<View style={{marginTop: 22}}>
<View>
<Text>{this.props.desc}</Text>
<Button
title="Fermer la fenêtre"
onPress={() => {
this.setModalVisible(!this.state.modalVisible);
}} />
</View>
</View>
</Modal>
<View style={styles.card_discord}>
<Image style={styles.card_discord_img} source={{ uri: this.props.img }} />
<LinearGradient
start={[1.0, 0.5]}
end={[0.0, 0.5]}
colors={['rgba(51, 51, 51, 0.2)', '#333333', '#333333']}
style={styles.FadeAway}>
<View style={styles.FadeAway}>
<Text h4 style={styles.FadeAway_h2}>
{this.props.title}
</Text>
<Text style={styles.FadeAway_p}>{this.props.desc}</Text>
</View>
</LinearGradient>
</View>
</TouchableOpacity>
</View>
);
}
}
My HomeScreen component (page where the error appears) :
export default class HomeScreen extends Component {
constructor(props) {
super(props);
this.ref = Fire.shared.firestore.collection('posts')
this.useref=
this.state={
dataSource : [],
}
}
feedPosts = (postSnapShot) =>{
const post = [];
postSnapShot.forEach((doc) => {
const {uid,text,timestamp,title_new,image} = doc.data();
const data=Fire.shared.firestore
.collection('users')
.doc(uid)
.get()
.then(doc=>{
post.push({
text,
timestamp,
title_new,
image,
uid,
})
this.setState({
dataSource : post,
});
})
});
}
renderPost=post=>{
return(
<View style={styles.card}>
<HorizontalCard title={post.title_new} desc={post.text} img={post.image} />
</View>
)
}
render() {
return (
<ThemeProvider>
<ScrollView>
<SwiperFlatList
autoplay
autoplayDelay={5}
index={0}
autoplayLoop
autoplayInvertDirection
data={this.state.dataSource}
renderItem={({item})=>this.renderPost(item)}
/>
...
<ScrollView>
</ThemeProvider>
)
}
}
I am new in React Native and I searched on Google but I only could find old version of React Native.
Actually, I am not sure how to pass state value to other js files
I am making Authpage that will redirect to tappage.js if the state value 'isValid' becomes 'true'
I am planning to change the page like this on App.js, if there are other better way, please let me know.
Thank you this is my code.
AuthManager.js
export default class AuthPage extends Component {
constructor(props) {
super(props);
this.state = {
user : null,
firebaseUser : null,
fcmToken : null,
accessToken : null,
authType : null,
hasInitialNotification : null,
isValid : false
};
this.unsubscribe = null;
}
...some codes..
render() {
// if (!this.state.firebaseUser) {
return (
<Provider store={store}>
<View style = {styles.main}>
<View style ={styles.logotemp}>
<Image style ={styles.logo}
source={require('../../resources/logo/logo.png')}
/>
</View>
<View style = {styles.inputid}>
<FormInput
ref={(el)=> {this.email = el;}}
textInputRef='email'
placeholder = "Email"
onChangeText={(email) => this.setState({email})}
value = {this.state.email}
/>
<FormInput
ref={(el)=> {this.password = el;}}
textInputRef='password'
onChangeText={(password) => this.setState({password})}
value = {this.state.password}
placeholder = "Password"
secureTextEntry = {true}
/>
<TouchableOpacity onPress={this._emailSignIn.bind(this)}>
<Image
style = {styles.loginbut}
source={require('../../resources/socialicon/signin.png')}
/>
</TouchableOpacity>
</View>
<View style = {styles.socialicons}>
<TouchableOpacity onPress={this._facebookSignIn.bind(this)} >
<Image
style={styles.fbicons}
source={require('../../resources/socialicon/facebook.png')}
/>
</TouchableOpacity>
<Image
style={styles.divider}
source = {require('../../resources/socialicon/divider.png')}
/>
<TouchableOpacity onPress={this._googleSignIn.bind(this)} >
<Image
style={styles.ggicons}
source={require('../../resources/socialicon/google.png')}
/>
</TouchableOpacity>
</View>
</View>
</Provider>
);
// }
if (this.state.firebaseUser) {
return(
<Provider store = {store}>
{store.isValid = this.state.isValid}
</Provider>
);
}
}
export default class MainPage extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
}
render() {
alert(store.isValid);
if(!this.props.isValid){
return(<View style={{flex:1}}>
<AuthPage></AuthPage>
</View>
);
}
if(isValid){
return(
<View style={{flex:1}}>
<TabPage></TabPage>
</View>
);
}
}
}
thank you!!
The idiom in React is that only the current element can know it's state.
I would highly recommend using Redux for the global data transfer between components, or, if you do not need data synced, you can use AsyncStorage.