react-native onPress binding with an argument

BindingReact Native

Binding Problem Overview


The desired behaviour is to pass an argument (text) to the onClick handler to console.log it but it seems that I'm doing something wrong with the syntax.

If I leave the argument out as below, it's working fine:

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress() {
    console.log('FOOOBAAR');
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress.bind(this)}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

However, if I want to pass an argument to the onPress handler, it complains 'Cannot read property 'bind' of undefined.

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress(txt) {
    console.log(txt);
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress('foo').bind(this)}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

Thanks

Addition: If I change it to:

onPress={this.onPress.bind('foo')}

it does not work either.

Binding Solutions


Solution 1 - Binding

You can do the binding in the constructor by using ES6:

export default class Nav extends Component {
  constructor(props) {
    super(props);

    this.onPress = this.onPress.bind(this);
  }

and then

  onPress(txt) {
    console.log(txt);
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={() => this.onPress('foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }
}

Solution 2 - Binding

You can avoid binding the function in the constructor by binding it at the onPress value and passing the argument after 'this'. You can refactor your code like so,

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress(txt) {
    console.log(txt);  // foo
  }
  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress.bind(this,'foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

The first argument is 'this' and any other arguments can be supplied after that which will be received in the same order.

Update : Can do this using closures too.

export default class Nav extends Component {
  componentDidMount() {
    this.props.pickNumber(3);
  }

  onPress = (this, txt) => () => {
    console.log(txt);  // foo
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={this.onPress(this,'foo')}>
          <Text>Go to Foo</Text>
        </TouchableHighlight>
      </View>
    );
  }

}

Solution 3 - Binding

You can solve it with fat arrows too:

export default class Nav extends Component {

  handlePress = (text) => {
    console.log(text);
  }

  render() {
    return (
      <View>
        <Text>####################</Text>
        <Text>Intro Screen</Text>
        <Text>Number: {this.props.numbers}</Text>
        <TouchableHighlight onPress={() => this.handlePress('weeeeee')}>
          <Text>Go to Foo</Text>
      </TouchableHighlight>
    </View>
    );
  }
}

Solution 4 - Binding

You should just pass one fat arrow function before calling the function.

onPress= {()=> this.handlePress(param)}

Solution 5 - Binding

Define function and call it onPress of Text. If you are iterating over array then you can also pass title

  selectText = (item) => {
      		console.log(item) // will print Text Pressed
      		alert(item)
      }
   return(
       <View>
       <Text onPress = {()=>this.selectText("Text Pressed")}>Press for Alert</Text>
       </View>
    }

Solution 6 - Binding

try this

const onChangeHandler = index => { console.log(index) }
onPress={onChangeHandler.bind(this, index)}

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
QuestionWastelandView Question on Stackoverflow
Solution 1 - BindingingaView Answer on Stackoverflow
Solution 2 - BindingGulshanZealousView Answer on Stackoverflow
Solution 3 - BindingTechnoTimView Answer on Stackoverflow
Solution 4 - BindingBinova GautamView Answer on Stackoverflow
Solution 5 - BindingGurjinder SinghView Answer on Stackoverflow
Solution 6 - BindingNasreen UstadView Answer on Stackoverflow