How to get props from a child view in react native - react-native

I have a react-native view like this.
<Parent>
<Header/>
</Parent>
The header is also a view with some text input fields and icons. The Parent is another view created by adding the Header component. So what I want to do is, when I type some text on the text field which is located in the Header view, I want to take that value to the Parent view props. How to do this??? I've tried some answers that showed in StackOverflow. But they didn't give me what I expected.
For someone who wants to see the full code, This is the parent screen.
export default class ParentScreen extends Component {
constructor(props) {
super(props);
this.state = {
objects: null,
indicator: true,
};
}
render(){
<View style={styles.container}>
<HeaderBar />
</View>
}}
And this is the Header screen.
export default class HeaderBar extends Component {
constructor(props) {
super(props);
}
state = {
searchEnabled: false
};
render() {
return (
<View style={styles.navigationBar}>
<View style={styles.titleArea}>
{this.state.searchEnabled === true ? (
<View style={styles.titleArea}>
<Icon
name="arrow-back"
type="Ionicons"
color="black"
onPress={() => this.setState({ searchEnabled: false })}
/>
<TextInput
placeholder="Search"
placeholderTextColor="white"
style={styles.input}
onChangeText={text => this.setState({ filterKey: text })}
/>
</View>
) : (
<View style={styles.titleArea}>
<Image
style={styles.profileImage}
source={require("../../images/user_image_1.jpg")}
/>
</View>
)}
</View>
</View>
);
}
}

Define a function in the parent View, something like:
onChangeText = (text) => {
this.setState({
myUpdatedText: text
})
}
Then, pass it to the child as a prop:
<HeaderBar onChangeText={this.onChangeText} />
So in the child code you can use it like:
<TextInput
placeholder="Search"
placeholderTextColor="white"
style={styles.input}
onChangeText={this.props.onChangeText}
/>

Related

Getting null instead of text

I'm trying to get the text from two text fields I have.
But when I try to log the text to the console it always prints nothing, It has the LOG tag of course, but nothing else.
This is my code:
class Login extends React.Component {
state = {
email : '',
password: '',
}
handleLogin = () => {
console.log(this.state.email);
};
render() {
return(
<View style={styles.superContainer}>
<View style={styles.formContainer}>
<AppTextInput
placeHolderText="Email#Address.com"
onChangeText={(text) => this.setState({email: text})}/>
<AppTextInput
placeHolderText="Password"
onChangeText={(text) => this.setState({password: text})}/>
</View>
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
onPress={this.handleLogin}
/>
</View>
</View>
);
}
}
I searched for an answer, but it seems like it should work. It is written just like in other answers I saw to the same question, and it is written like that on the docs I saw.
What am I doing wrong?
As request, I added an image of the console:
EDIT: I now tried to change the 'email' in the this.state part, when logging it is showing, it seems like the TextInput won't get the text on onChangeText
Try this:
import {TextInput} from 'react-native';
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
}
handleLogin = () => {
console.log(this.state.email);
};
render() {
return(
<View style={styles.superContainer}>
<View style={styles.formContainer}>
<TextInput
placeHolderText="Email#Address.com"
onChangeText={(email) => this.setState({email})}/>
<TextInput
placeHolderText="Password"
onChangeText={(password) => this.setState({password})}/>
</View>
<View style={styles.buttonContainer}>
<AppButton
title="LOGIN"
onPress={this.handleLogin}
/>
</View>
</View>
);
}
}
I can verify that the following code is working on Snack, I have slightly modified some elements (nothing major) and used the alert, instead of console.log. You may directly paste it onto snack to view the result.
import {TextInput} from 'react-native';
import React from 'react'
import { Text, View, Button } from 'react-native';
class Login extends React.Component {
state = {
email : '',
password: '',
}
handleLogin = () => {
alert(this.state.password + " " + this.state.email);
};
render() {
return(
<View>
<View>
<TextInput
placeHolderText="Email#Address.com"
onChangeText={(text) => this.setState({email: text})}/>
<TextInput
placeHolderText="Password"
onChangeText={(text) => this.setState({ password: text })}
/>
</View>
<View >
<Button
title="LOGIN"
onPress={this.handleLogin}
/>
</View>
</View>
);
}
}
export default Login;
Finally figured it out, the problem was that I was using a custom TextInput (aka AppTextInput) and didn't pass it the onChangeText.
Adding to AppTextInput onChangeText={this.props.onChangeText} fixed the issue.
This is the full render function of AppTextInput:
render() {
const { isFocused } = this.state;
const {onFocus, onBlur, onChangeText} = this.props;
return (
<TextInput
placeholder= {this.props.placeHolderText}
selectionColor = {COLORS.appOrange}
underlineColorAndroid={
isFocused ? COLORS.appOrange : COLORS.appGray
}
onChangeText={this.props.onChangeText}
onFocus = {this.handleFocus}
onBlur = {this.handleBlur}
style = {styles.textInput}
/>
);
}

Passing multiple data through to next scene

I'm lost as to how to send through multiple input of data through to the next scene in my app. I have no problem with sending through one input of data "text1".
This is my sample code below.
import { Actions } from 'react-native-router-flux';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
text1: '',
text2: '',
};
}
render() {
return (
<View>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
onChangeText={text1 => this.setState({ text1 })}
/>
</View>
<View style={styles.inputContainer}>
<TextInput
style={styles.input}
underlineColorAndroid="transparent"
onChangeText={text2 => this.setState({ text2 })}
/>
</View>
<TouchableOpacity
style={styles.btnNext}
onPress={this.onPressNext.bind(this)}>
<Text style={styles.btnText}>Next</Text>
</TouchableOpacity>
);
}
Below is where i think needs fixing because the + sign isn't allowing to pass two states?
onPressNext() {
Actions.scene2({text1: this.state.text1} +
{text2: this.state.text2});
}
}
Instead of trying to pass 2 different objects, just pass it like:
Actions.scene2({text1: this.state.text1,
text2: this.state.text2})

How to send data to another page in react-native

I have Main component and Bar component. I want to send some info to Bar component.
This is my code:
render() {
<View>
<View>
<Bar />
</View>
<View>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Bar', { Info:'test' }) }>
</TouchableOpacity>
</View>
<View/>
}
I cant send like this because Bar component is in this component. How Can I fix this.
Since your're in the same component ... setState is your answer
class Comp extends React.Component {
state = {
info: '',
};
render() {
const { info } = this.state;
return (
<View>
<View>
<Bar info={info} />
</View>
<View>
<TouchableOpacity
onPress={() => {
this.setState({ info: 'test' });
}}
/>
</View>
</View>
);
}
}
State There are two types of data that control a component: props and
state. props are set by the parent and they are fixed throughout the
lifetime of a component. For data that is going to change, we have to
use state.

Change the color of Button when onFocus input

Good Morning , I tried a simple component with react-native that changes the color of my button while onFocus().I can't find how to change the color . Here is my component . Have you any ideas ?
import React, {Component} from 'react';
import {
StyleSheet,Text, View, Button,
} from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.inputContainer}>
<TextInput
maxHeight={200}
style={styles.textInput}
ref={(r) => {
this.textInputRef = r;
}}
placeholder={'Message'}
underlineColorAndroid="transparent"
onFocus={()=>{/*Here i awant to change the color of Button }}
testID={'input'}
/>
<Button color="transparent" id="ScanButton"
onPress={() => this.setState({text: 'Placeholder Text'})}
title="Scan Barcode"
/>
</View>
)}
First Initialize your variable
constructor(props) {
super(props);
this.state = {
isFocus: false
}
}
In your TextInput add two props onFocus() and onBlur()
<TextInput
maxHeight={200}
style={styles.textInput}
ref={(r) => {
this.textInputRef = r;
}}
placeholder={'Message'}
underlineColorAndroid="transparent"
onBlur={() => this.onBlur()}
onFocus={() => this.onFocus()}
testID={'input'}
/>
add two methods in your class to change the state
onFocus() {
this.setState({
isFocus: true
})
}
onBlur() {
this.setState({
isFocus: false
})
}
and your button style will be like that
<Button
color={this.state.isFocus ? 'red' : 'green'}
id="ScanButton"
onPress={() => this.setState({text: 'Placeholder Text'})}
title="Scan Barcode"
/>
style={{color: this.props.focused ? '#8B327C' :'#3F8B99'}}
try something like this

Render handler to be called when the user hits return key

I am creating a todo list. For the TextInput I do not want to use a button and the "onPress: () =>" handler to call my function with the users given text. Instead, I would like the user to just be able to hit the return key to call my function. It doesn't seem that react-native has an "onReturnKey" handler. Any suggestions for how I should go about this?
...
class App extends Component {
constructor(props) {
super(props);
this.state = { newTodo: '' };
}
AddNewTodo(text) {
return console.log(text);
}
render() {
return (
<View>
<Header headerText="VANO" />
<Card>
<CardSection style={{ backgroundColor: '#f7f7f7' }}>
<Text style={styles.titleStyle}>
Reminders
</Text>
</CardSection>
<CardSection>
<Input
placeholder="Create Reminder"
returnKeyType='done'
onChangeText={(text) => this.setState(this.newTodo: text)}
onSubmitEditing={() => this.AddNewTodo(this.state.newTodo)}
value={this.state.newTodo}
/>
</CardSection>
...
The TextInput component has a prop for returnKeyType. You can use that in conjunction with onSubmitEditing to run a function when the return key is pressed.
Example:
constructor() {
this.state = { new_todo: '' }
}
render() {
return (
....
<TextInput
returnKeyType={"done"}
onChangeText={(text) => { this.setState(new_todo: text) }}
onSubmitEditing={() => { myFunctionToAddNewTodo(this.state.new_todo) }}
value={this.state.new_todo}/>
...
)
}