user1432031
user1432031

Reputation: 173

How to update a text input on change

I'm trying to update a text input as it changes but it doesn't seem to work.

Here's my simplified example:

  var Message = React.createClass({

  getInitialState: function() {
    return {textValue: ''};
  },

  render: function() {
    return (
      <View style={[styles.container]}>
        <ProfilePicture userId={this.props.userId}/>
        <TextInput
          ref={component => this._textInput = component}
          style={{flex: 8, paddingLeft: 5, fontSize: 15}}
          onChangeText={this._handleChange} 
          //multiline={true}
          defaultValue={""}
          value={this.state.textValue}
          returnKeyType={"send"}
          blurOnSubmit={false}
          autoFocus={true}
          enablesReturnKeyAutomatically={true}
          onSubmitEditing={this._onSubmit}
        />
      </View>
    ); 
  },

  _handleChange: function(text) {
    this.setState({textValue: "foo"});
  },

  _onSubmit: function(event) {
    this._clearText();
  },

  _clearText: function() {
    this._textInput.setNativeProps({text: ''});
  },

});

I'm expecting that as soon as someone enters in some text it gets automatically altered to read "foo" but this doesn't work.

Any ideas?

UPDATE

Plot thickens,

If I call the same function for onBlur it works but only when there is no text already in the text input. If I change the function to set the value using this._textInput.setNativeProps({text: 'foo'}); instead of this.setState({textValue: "foo"}); then it works both when the text input is empty and has data.

Example:

render: function() {
  return (
    <TextInput
      ref={component => this._textInput = component}
      style={{flex: 8, paddingLeft: 5, fontSize: 15}}
      onChangeText={this._handleChange} 
      onBlur={this._handleChange}
      //multiline={true}
      defaultValue={""}
      value={this.state.textValue}
      returnKeyType={"send"}
      blurOnSubmit={false}
      autoFocus={true}
      enablesReturnKeyAutomatically={true}
      onSubmitEditing={this._onSubmit}
    />
    ); 
},

_handleChange: function(text) {
  // what to do here check if there are youtube videos?
  this._textInput.setNativeProps({text: 'foo'});
}

So in the above the _handleChange works for onBlur but not for onChangeText. Weird right?

Upvotes: 3

Views: 11811

Answers (2)

user1432031
user1432031

Reputation: 173

Not really an optimal solution but looking at the react native code for react-native v 0.17.0 it looks like any changes made to the component's value during onChange don't take affect.

The code has changed on HEAD and this could fix it. https://github.com/facebook/react-native/blob/master/Libraries/Components/TextInput/TextInput.js#L542

To get around this you can wrap the code to reset the text inputs value in a setTimeout like this

var self = this;
setTimeout(function() {self._textInput.setNativeProps({text: newText}); }, 1);

This creates a new change outside of the current change event.

Like I said not an optimal solution but it works.

There is another issue that the cursor position needs to be updated if the new text is larger than the old text, this isn't available on master yet but there is a PR that looks like it is close to being merged. https://github.com/facebook/react-native/pull/2668

Upvotes: 4

rmevans9
rmevans9

Reputation: 5643

You need to bind your onChangeText to this. Without that in the _handleChange function "this" does not refer to the component and thus setState is not going to work the way you expect it to.

<TextInput
    ref={component => this._textInput = component}
    style={{flex: 8, paddingLeft: 5, fontSize: 15}}
    onChangeText={this._handleChange.bind(this)} // <-- Notice the .bind(this)
    //multiline={true}
    defaultValue={""}
    value={this.state.textValue}
    returnKeyType={"send"}
    blurOnSubmit={false}
    autoFocus={true}
    enablesReturnKeyAutomatically={true}
    onSubmitEditing={this._onSubmit}
/>

Upvotes: 2

Related Questions