Proper use of onChangeText in React Native

Viewed 12154

I am fairly new to React Native and I have problem with using onChangeText. I am trying to have a TextInput to type in a word and updating a state. When I use onChangeText I can only type 1 symbol at a time until it re-renders. I can keep the value by using value = {this.state.text} but the input field still lose focus everytime I write a letter.

I have also tried using onBlur and onSubmitEditing with no success.

This is my current code. Which is inside render().

 <View style={{padding: 10}}>
   <TextInput
    onChangeText={(text) => { this.setState({text: text})} }
    />
    <TouchableHighlight style={styles.button} onPress={this.handlePress.bind(this)}>
         <Text style={styles.buttonText}>Login</Text>
       </TouchableHighlight>
            <Text style={{padding: 10, fontSize: 42}}>
      {this.state.text}
    </Text>
  </View>

So by using this method I can currently only write one letter at a time as this.state.text will only consist of one letter at a time.

Any help appreciated.

Example

SOLVED

I used react-native-tab-view which uses it's own router. I wrote my code as this And as you see the rendering part happens outside of return(). That's what caused my problem. I've removed react-native-tab-view and rewritten it like this

3 Answers
<TextInput style={styles.input}
     placeholder='username'
     onChangeText={(text) => { this.setState({ username: text})}}>
</TextInput>

You need { } to open and close the function block, else it return the setState

() => callFn is equivalent with () => {return callFn} so you return your setState call. You need here () => {callFn}

And remove the {this.state.text} from your <Text> tag, that will trigger rerender every time you change the state

Try with this full component hope so this helpfull for u.

'use strict';

import React, { Component } from "react";
import { Text, View, TextInput } from 'react-native';

class Home extends Component {

    constructor(props) {
        super(props);
        this.state = {
            text:''
        };
    }

    render() {
        let {text}=this.state;

        return ( 
            <View style={{padding: 10}}>
                <TextInput onChangeText={(text) => { this.setState({ text: text})}}/>
                    <Text style={{padding: 10, fontSize: 42}}>
                    {text}
                    </Text>
            </View>
        )
     }
  }

  export default Home;

It is not best practice to create functions within component props. This will always force a re-render even if nothing was changed due to the fact that the prop value is a new function. Try it like this. I also gave you a way to have multiple text inputs without creating a single inline function by use of "currying", along with making them into controlled inputs whereby their value is "controlled" by the state. Socialism in React!

'use strict';

import React, { Component } from "react";
import { Text, View, TextInput, StyleSheet } from 'react-native';

class Home extends Component {

  constructor(props) {
    super(props);
    this.state = {
      name:''
      email:''
      nameError:''
      emailError:''
    };
  }

  onChangeText = name => text => this.setState({ [name]: text });

  render() {
    let { name, email, nameError, emailError } = this.state;

    return ( 
      <View style={styles.container}>
        <TextInput onChangeText={this._onChangeText("name")} value={name} />
        <Text style={styles.text}>{nameError}</Text>
        <TextInput onChangeText={this._onChangeText("email"} value={email} />
        <Text style={styles.text}>{emailError}</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  text: {
    padding: 10,
    fontSize: 42
  },
  container: {
    padding: 10
  }
});

export default Home;
Related