Passing React Native Input Field to State - react-native

Background
I am working with a React Native application and I have a login form. The login form input field is passing email to state on button click.
I am trying to console.log the email field. this.state.email but I keep getting email not defined.
I have removed the firebase functions to make it easier to read. But at the top of the form the console.log never succeeds.
Examples
These are the components I am working with.
Input Component
This input component is to be used in LoginForm.
class Input extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
onChangeText: ''
}
}
render() {
return(
<View}>
<Text>{this.props.label}</Text>
<TextInput
value={this.value}
onChangeText={this.onChangeText}
/>
</View>
);
}
}
LoginForm Component
class LoginForm extends Component {
constructor(props) {
super(props);
this.state = {
email: '',
};
}
signIn() {
console.log(this.state.email);
}
render() {
return(
<Card>
<CardSection>
<Input
value={this.state.email}
onChangeText={(email) => this.setState({email})}
/>
</CardSection>
<CardSection>
<Button
onPress={() => this.signIn()}
btnTxt='Sign In'
/>
</CardSection>
</Card>
);
}
Question
What is the proper way to pass the input field "email" to state so I can use it in my Firebase Authentication function?

In the code featured in your question, your Input component is calling this.onChangeText on onChangeText, this isn't referencing the same function you passed down as a prop from LoginForm.
class Input extends Component {
constructor(props) {
super(props);
this.state = {
value: '',
onChangeText: '',
};
}
render() {
return (
<View>
<Text>{this.props.label}</Text>
<TextInput
value={this.value}
onChangeText={email => this.props.onChangeText(email)}
/>
</View>
);
}
}

Related

Figure out if TextInput has focus via ref

The configuration is as follows:
class MyComponent extends Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
...
render() {
...
<TextInput style={styles.textInput}
...
ref={this.inputRef}
/>
...
}
}
Q. How to find out if TextInput has focus within a render() method?
you can check either by using this functions or by creating your custom setup by registering onBlur() and onFocus() callback functions in your textInput.
e.g.
<TextInput
onFocus={() =>console.log("focus received" ) }
onBlur={() => console.log("focus lost") } />

my Button cannot change a state in another react native component

Why does the following code not work? In this test I simply try to show a state of the component Board, when the Button is clicked. But I get a TypeError: undefined is not an object.
var board = (<Board/>);
return (
<View>
{ board }
<Button
title="Press me"
onPress={() => Alert.alert(board.state.lastRefresh)}
/>
</View>
);
};
The Board component has this constructor:
constructor(props) {
super(props)
this.state = {
lastRefresh: Date(Date.now()).toString(),
}
...
If your Board component is something like this:
import PageTwo from 'PageTwo';
export default class Board extends React.Component {
constructor(props) {
super(props);
this.state = {
lastRefresh: Date(Date.now()).toString(),
}
}
render() {
return (
<View>
<PageTwo lastRefresh={this.state.lastRefresh}>
</PageTwo>
</View>
)
}
}
You can access your props by this way from PageTwo component:
export default class PageTwo extends React.Component {
render() {
return (
<View>
<Button
title="Press me"
onPress={() => Alert.alert(this.props.lastRefresh)}
/>
</View>
)
}
}

Passing data back to component by react-native navigation

I have main App.js where i implemented StackNavigator:
export default class App extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="MainPage" component={MainPage} />
<Stack.Screen name="Submit" component={Submit} />
</Stack.Navigator>
</NavigationContainer>
);
}
}
What i want to do is Pass data from Submit component into my MainPage and display it in ScrollView from array: arr in state of MainPage.
Mainpage looks like this. I want to pass function addNode to adding node into state of my MainPage:
class MainPage extends Component {
constructor(props) {
super(props);
this.state = {
arr: [],
liters: '',
time: '',
};
}
addNode = (time, liters) => {
if (this.state.time) {
this.state.arr.push({calc: time + liters});
this.setState({time: ''});
this.setState({liters: ''});
}
};
onPress = () => {
this.props.navigation.navigate('Submit', {addNode: this.addNode});
};
render() {
return (
<View>
<ScrollView>{this.state.arr}</ScrollView>
<TouchableOpacity onPress={this.onPress}>
<Text>+</Text>
</TouchableOpacity>
</View>
);
}
}
My Submit component looks like this. on button Submit i want to pass data from inputs to MainPage, add it to array and then display it in scroll view:
class Submit extends Component {
constructor(props) {
super(props);
this.state = {
liters: '',
time: '',
};
}
goBack() {
this.props.navigation.goBack();
this.props.navigation.state.params.addNode({
time: this.state.time,
liters: this.state.liters,
});
}
render() {
return (
<View>
<Text>Form</Text>
<TextInput
onChangeText={time => this.setState({time})}
value={this.state.time}
/>
<TextInput
onChangeText={liters => this.setState({liters})}
value={this.state.liters}
/>
<Button title="Submit" onPress={this.goBack} />
</View>
);
}
}
When i click Submit from my Submit component i get error presented in this screen:
My question is, how to pass data back to parent component from children component using StackNavigator? What im doing wrong here?

How would I disable a function by clicking on TextInput

I have this class for blinking text:
class BlinkerFluid extends React.Component {
constructor(props) {
super(props);
this.state = {
isShowingText: true,
TextInputName = ''
};
setInterval(() => {
this.setState(previousState => {
return { isShowingText: !previousState.isShowingText };
});
}, 700);
}
render () {
let display = this.state.isShowingText ? this.props.text : ' ';
return (
<Text style={styles.other}>{display}</Text>
);
}
}
And this class to render the blinking text:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { text: 'x' };
}
render() {
return (
<View style={styles.container}>
<Text style={styles.other}>$ root | > </Text>
<BlinkerFluid text=' _' />
<TextInput style={styles.lol}
onChangeText={(text) => this.setState({text})}
value={this.state.text}
/>
</View>
);
}
}
I want to be able to stop the blinking of the text when I click on the TextInput prop and/or write to it.
How would I go about doing that?
I've been trying to search for an answer on my own, read the docs, but nothing has helped.
Any help is appreciated!
You could try something like the below code snippet (I've only included the code for App. You can implement the paused functionality in the BlinkerFluid however you want.
Basically, I'm storing in the state whether the blinker should be paused or not, then passing that value through to the BlinkerFluid component as a prop. You can set the pauseBlinker state easily, perhaps on onChangeText as in the example, or on press of a TouchableOpacity element etc.
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
text: 'x',
pauseBlinker: false,
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.other}>$ root | > </Text>
<BlinkerFluid text=' _' paused={this.state.pauseBlinker} />
<TextInput style={styles.lol}
onChangeText={(text) => this.setState({ text, pauseBlinker: true, })}
value={this.state.text}
/>
</View>
);
}
}

loading/importing contents of Modal from another js (class) file in react-native

My modal displays an input form. I want to import contents of my Modal from another js file for keeping the main code shorter. I am actually able to import contents of my Modal from another class file by calling component's class name as jsx tag, but in this case I cannot pass state variables of main component to inner component of the modal or vice versa. And, I don't know if it is possible to receive data from the modal in this case. I know that I could use navigator with passProps, but I want to use just a modal for this purpose. For instance:
this is main Component:
class Main extends React.Component {
constructor(props){
super(props);
this._showAddNewModal = this._showAddNewModal.bind(this);
this.state = {
addNewShow: false,
mytext: '' // this should be updated through Modal.
}
}
render(){
return (
<TouchableHighlight onPress={() => {this._showAddNewModal();}}>
<Text> Show my modal </Text>
</TouchableHighlight>
<Modal visible={this.state.addNewShow}>
<MyModalContents />
</Modal>
);
}
_showAddNewModal(){
this.setState({addNewShow: true});
}
}
this is the component to be displayed in the modal:
class MyModalContents extends React.Component { // extends Modal?
constructor(props){
super(props);
this.state = {mytext: ''}
}
render(){
<View>
<TextInput onChangeText={(text) => this.setState({mytext: text})} />
</View>
}
}
I can't even close the modal because the state of 'addNewShow' is not accessible from MyModalContents. Any help will be appreciated.
You can pass props to a child component by cloning it with React.cloneElement. Here's an example of how you could use it with your modal:
class Main extends React.Component {
constructor(props){
super(props);
this.state = {
mytext: '' // this should be updated through Modal.
}
}
_showAddNewModal(){
this.refs.modal.show();
}
render(){
return <View>
<TouchableHighlight onPress={this._showAddNewModal}>
<Text> Show my modal </Text>
</TouchableHighlight>
<Modal parent={this} ref="modal">
<MyModalContents />
</Modal>
</View>
}
}
Modal
class Modal extends React.Component {
constructor(props){
super(props);
this.state = {
visible: false,
}
}
show() {
this.setState({visible: true});
}
close(){
this.setState({visible: false});
}
render(){
return <View style={{opacity: this.state.visible ? 1 : 0}} pointerEvents={this.state.visible ? 'auto' : 'none'}>
{/* can pass props with second argument */}
{React.cloneElement(this.props.children, {
parent: this.props.parent,
modal: this
})}
</View>
}
}
MyModalContents
class MyModalContents extends React.Component {
constructor(props){
super(props);
}
_updateModalState() {
const self = this;
// will update the "Main" component state as props are passed through modal
this.props.parent.setState({myText: 'Updated Text!'}, () => {
self.props.modal.close();
});
}
render(){
return <View>
<TouchableHighlight onPress={this._updateModalState}>
<Text> Update Modal State </Text>
</TouchableHighlight>
</View>
}
}