react native get TextInput value

React Native

React Native Problem Overview


I am stuck with a very simple problem. I have login form with username, password and button. In my button handler, I try to get the textinput value. But always get undefined value. Am I missing something?

render() {
        <ExScreen
          headerColor={this.state.headerColor}
          scrollEnabled={this.state.enableScroll}
          style={styles.container} >
          <View >
            <View  >
              <View style={[styles.inputContainer]} >
                <TextInput
                  ref= "username"
                  onChangeText={(text) => this.setState({text})}
                  value={this.state.username}
                />
              </View>
 <Button style={{color: 'white', marginTop: 30, borderWidth: 1, borderColor: 'white', marginLeft: 20*vw, marginRight: 20*vw, height: 40, padding: 10}} 
             onPress={this._handlePress.bind(this)}>
              Sign In
            </Button>   
...
 _handlePress(event) {
    var username=this.refs.username.value;

React Native Solutions


Solution 1 - React Native

The quick and less optimized way to do this is by using arrow function inside your onChangeText callback, by passing username as your argument in your onChangeText callback.

<TextInput
    ref= {(el) => { this.username = el; }}
    onChangeText={(username) => this.setState({username})}
    value={this.state.username}
/>

then in your _handlePress method

_handlePress(event) {
    let username=this.state.username;
}

But this has several drawbacks!!!

  1. On every render of this component a new arrow function is created.
  2. If the child component is a PureComponent it will force re-renders unnecessarily, this causes huge performance issue especially when dealing with large lists, table, or component iterated over large numbers. More on this in React Docs

Best practice is to use a handler like handleInputChange and bind ```this`` in the constructor.

...
constructor(props) {
  super(props);
  this.handleChange= this.handleChange.bind(this);
}

...
handleChange(event = {}) {
  const name = event.target && event.target.name;
  const value = event.target && event.target.value;

  this.setState([name]: value);
}
...

render() {
  ...
  <TextInput
    name="username"
    onChangeText={this.handleChange}
    value={this.state.username}
  />
  ...
}

...

Or if you are using es6 class property shorthand which autobinds this. But this has drawbacks, when it comes to testing and performance. Read More Here

...
handleChange= (event = {}) => {
  const name = event.target && event.target.name;
  const value = event.target && event.target.value;

  this.setState([name]: value);
}
...

render() {
  ...
  <TextInput
    name="username"
    onChangeText={this.handleChange}
    value={this.state.username}
  />
  ...
}

...

Solution 2 - React Native

In React Native 0.43: (Maybe later than 0.43 is OK.)

_handlePress(event) {
    var username= this.refs.username._lastNativeText;

enter image description here

Solution 3 - React Native

You should use States to store the value of input fields. https://facebook.github.io/react-native/docs/state.html

  • To update state values use setState

> onChangeText={(value) => this.setState({username: value})}

  • and get input value like this

> this.state.username

Sample code

export default class Login extends Component {
		
	state = {
		username: 'demo',
		password: 'demo'
	};
	
	<Text style={Style.label}>User Name</Text>
	<TextInput
		style={Style.input}
		placeholder="UserName"
		onChangeText={(value) => this.setState({username: value})}
		value={this.state.username}
	/>
	
	<Text style={Style.label}>Password</Text>
	<TextInput
		style={Style.input}
		placeholder="Password"
		onChangeText={(value) => this.setState({password: value})}
		value={this.state.password}
	/>

	<Button
		title="LOGIN"
		onPress={() => 
			{
				if(this.state.username.localeCompare('demo')!=0){
					ToastAndroid.show('Invalid UserName',ToastAndroid.SHORT);
					return;
				}

				if(this.state.password.localeCompare('demo')!=0){
					ToastAndroid.show('Invalid Password',ToastAndroid.SHORT);
					return;
				}

				//Handle LOGIN

			}
		}
	/>

Solution 4 - React Native

If you are like me and doesn't want to use or pollute state for one-off components here's what I did:

import React from "react";
import { Text, TextInput } from "react-native";
   
export default class Registration extends Component {
  _register = () => {
    const payload = {
      firstName: this.firstName,
      /* other values */
    }
    
    console.log(payload)
  }
    
  render() {
    return (
      <RegisterLayout>
        <Text style={styles.welcome}>
          Register
        </Text>

        <TextInput
          placeholder="First Name"
          onChangeText={(text) => this.firstName = text} />

        {/*More components...*/}

        <CustomButton
          backgroundColor="steelblue"
          handlePress={this._register}>
          Submit
        </CustomButton>
     </RegisterLayout>
    )
  }
}

Solution 5 - React Native

export default class App extends Component {
  state = { username: '', password: '' }

  onChangeText = (key, val) => {
    this.setState({ [key]: val})
  }
  
  render() { 
    return (
      <View style={styles.container}>
          <Text>Login Form</Text>
          <TextInput
            placeholder='Username'
            onChangeText={val => this.onChangeText('username', val)}
            style={styles.input}
          />
          <TextInput
            placeholder='Password'
            onChangeText={val => this.onChangeText('password', val)}
            style={styles.input}
            secureTextEntry={true}
          />      
      </View>
    );
  }
}

Hope this will solve your problem

Solution 6 - React Native

This work for me

    <Form>

    <TextInput
    style={{height: 40}}
    placeholder="userName"
    onChangeText={(text) => this.userName = text}
    />

    <TextInput
    style={{height: 40}}
    placeholder="Password"
    onChangeText={(text) => this.Password = text}
    />


    <Button 
    title="Sign in!" 
    onPress={this._signInAsync} 
    />

    </Form>

and

  _signInAsync = async () => {
        console.log(this.userName)
        console.log(this.Password) 
  };

Solution 7 - React Native

Please take care on how to use setState(). The correct form is

this.setState({
      Key: Value,
    });

And so I would do it as follows:

onChangeText={(event) => this.setState({username:event.nativeEvent.text})}
...    
var username=this.state.username;

              

Solution 8 - React Native

Try Console log the object and you will find your entered text inside nativeEvent.text

example:

handelOnChange = (enteredText) => {
    console.log(enteredText.nativeEvent.text)
}
render()
return (
    <SafeAreaView>
        <TextInput
            onChange={this.handelOnChange}
        >
</SafeAreaView>

)

Solution 9 - React Native

constructor(props) {
        super(props);

        this.state ={
            commentMsg: ''         
        }
    }

 onPress = () => {
          alert("Hi " +this.state.commentMsg)
      }

 <View style={styles.sendCommentContainer}>

     <TextInput
        style={styles.textInput}
        multiline={true}
        onChangeText={(text) => this.setState({commentMsg: text})}
        placeholder ='Comment'/>

       <Button onPress={this.onPress} 
           title="OK!"
           color="#841584"
        />
     
  </TouchableOpacity>

</View>

Solution 10 - React Native

Simply do it.

this.state={f_name:""};

textChangeHandler = async (key, val) => {
    await this.setState({ [key]: val });
}

<Textfield onChangeText={val => this.textChangeHandler('f_name', val)}>

Solution 11 - React Native

Every thing is OK for me by this procedure:

<Input onChangeText={this.inputOnChangeText} />

and also:

inputOnChangeText = (e) => {
  this.setState({
    username: e
  })
}

Solution 12 - React Native

React Native Latest -> Simple and easy solution using state based approach.

const [userEmail, setUserEmail] = useState(""); 

<TextInput
          value={userEmail}
          style={styles.textInputStyle}
          placeholder="Email"
          placeholderTextColor="steelblue"
          onChangeText={(userEmail) => setUserEmail(userEmail)}
        />

Solution 13 - React Native

If you set the text state, why not use that directly?

_handlePress(event) {
  var username=this.state.text;

Of course the variable naming could be more descriptive than 'text' but your call.

Solution 14 - React Native

There is huge difference between onChange and onTextChange prop of <TextInput />. Don't be like me and use onTextChange which returns string and don't use onChange which returns full objects.

I feel dumb for spending like 1 hour figuring out where is my value.

Solution 15 - React Native

You dont need to make a new function for taht. just make a new useState and use it in onchange.

const UselessTextInput = () => {
  const [text, onChangeText] = React.useState("Useless Text");
  const [number, onChangeNumber] = React.useState(null);

  return (
    <SafeAreaView>
      <TextInput
        style={styles.input}
        onChangeText={onChangeText}
        value={text}
      />
      <TextInput
        style={styles.input}
        onChangeText={onChangeNumber}
        value={number}
        placeholder="useless placeholder"
        keyboardType="numeric"
      />
    </SafeAreaView>
  );
};

Solution 16 - React Native

This piece of code worked for me. What I was missing was I was not passing 'this' in button action:

 onPress={this._handlePress.bind(this)}>
--------------

  _handlePress(event) {
console.log('Pressed!');

 var username = this.state.username;
 var password = this.state.password;

 console.log(username);
 console.log(password);
}

  render() {
    return (
      <View style={styles.container}>

      <TextInput
      ref="usr"
      style={{height: 40, borderColor: 'gray', borderWidth: 1 , marginTop: 10 , padding : 10 , marginLeft : 5 , marginRight : 5 }}
      placeHolder= "Enter username "
      placeholderTextColor = '#a52a2a'

      returnKeyType = {"next"}
      autoFocus = {true}
      autoCapitalize = "none"
      autoCorrect = {false}
      clearButtonMode = 'while-editing'
      onChangeText={(text) => {
          this.setState({username:text});
        }}
      onSubmitEditing={(event) => {
     this.refs.psw.focus();

      }}
      />

      <TextInput
      ref="psw"
      style={{height: 40, borderColor: 'gray', borderWidth: 1 , marginTop: 10,marginLeft : 5 , marginRight : 5}}
      placeholder= "Enter password"
      placeholderTextColor = '#a52a2a'
      autoCapitalize = "none"
      autoCorrect = {false}
      returnKeyType = {'done'}
      secureTextEntry = {true}
      clearButtonMode = 'while-editing'
      onChangeText={(text) => {
          this.setState({password:text});
        }}
      />

      <Button
        style={{borderWidth: 1, borderColor: 'blue'}}
        onPress={this._handlePress.bind(this)}>
        Login
      </Button>

      </View>
    );``
  }
}

Solution 17 - React Native

User in the init of class:

constructor() {
  	super()
  	this.state = {
    	email: ''
	}
}

Then in some function:

handleSome = () => { console.log(this.state.email) };

And in the input:

<TextInput onChangeText={(email) => this.setState({email})}/>

Solution 18 - React Native

Did you try

var username=this.state.username;

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWayneZhaoView Question on Stackoverflow
Solution 1 - React NativeferndopolisView Answer on Stackoverflow
Solution 2 - React NativejiexishedeView Answer on Stackoverflow
Solution 3 - React NativeHitesh SahuView Answer on Stackoverflow
Solution 4 - React NativeJohnnyQView Answer on Stackoverflow
Solution 5 - React NativeMithhuView Answer on Stackoverflow
Solution 6 - React NativeRyosuke HujisawaView Answer on Stackoverflow
Solution 7 - React NativeandreaswienesView Answer on Stackoverflow
Solution 8 - React NativeNishit SehgalView Answer on Stackoverflow
Solution 9 - React NativeKeshav GeraView Answer on Stackoverflow
Solution 10 - React NativeAli AkramView Answer on Stackoverflow
Solution 11 - React NativeEhsan NouriView Answer on Stackoverflow
Solution 12 - React NativeAbdul Basit RishiView Answer on Stackoverflow
Solution 13 - React NativeBruce Xinda LinView Answer on Stackoverflow
Solution 14 - React NativeOndřej ŠevčíkView Answer on Stackoverflow
Solution 15 - React NativeMehrad FarahnakView Answer on Stackoverflow
Solution 16 - React NativeVinay HosamaneView Answer on Stackoverflow
Solution 17 - React NativeGiovanny GonzalezView Answer on Stackoverflow
Solution 18 - React Nativeprogrammer123View Answer on Stackoverflow