0

The question is almost similar to this one : touchableopacity onpress function undefined (is not a function) React Native

But the problem is, I am getting the error despite the fact that I have bind the function. Here is my TouchableOpacity component:

<TouchableOpacity style={styles.eachChannelViewStyle}  onPress={() => this.setModalVisible(true)}>

    {item.item.thumbnail ?
    <Image style={styles.everyVideoChannelThumbnailStyle} source={{uri: item.item.thumbnail}} />
   : <ActivityIndicator style= {styles.loadingButton} size="large" color="#0000ff" />}

    <Text numberOfLines={2} style={styles.everyVideoChannelVideoNameStyle}>
      {item.item.title}
    </Text>
  </TouchableOpacity>

And this is my setModalVisible function:

  setModalVisible(visible) {
    console.error(" I am in set modal section ")
    this.setState({youtubeModalVisible: visible});
  }

Also, I have bind the function in constructor as follows:

this.setModalVisible = this.setModalVisible.bind(this);

But, I am still getting same error that undefined is not a function. Any help regarding this error?

JustABeginner
  • 785
  • 2
  • 11
  • 26
  • that looks a bit weird. If you have done all the steps you said, you should not have this issue. Would you mind to post all the code of the component you are talking about? – quirimmo Dec 23 '18 at 16:21
  • The component that I am talking is TouchableOpacity. I am actually opening a modal when that touchableOpacity is pressed. But it calls that error everytime! – JustABeginner Dec 23 '18 at 16:25
  • I mean the code of your component where you use it – quirimmo Dec 23 '18 at 16:26
  • https://pastebin.com/idLWscLu here is that code – JustABeginner Dec 23 '18 at 16:32
  • 1
    The problem is the `renderEachChannelView` function. You haven't bound the value of `this` of *that* function so when you use `this` inside it, it doesn't point to what you want. You have to bind *all* methods in the class, or (preferably) define them with arrow functions. – JJJ Dec 23 '18 at 16:50
  • Thank you so much https://stackoverflow.com/users/502381/jjj ... I just bind the renderEachChannelView function and then it started working.... GOD I was waiting for this moment... – JustABeginner Dec 23 '18 at 16:53

2 Answers2

0

The render method and your custom method must be under the same scope. In code below I have demonstrated the same. I hope you will modify your code accordingly as I assume you got the gist :)

class Demo extends Component {
  onButtonPress() {
    console.log("click");
  }

  render() {
    return (
        <View>
          <TouchableOpacity onPress={this.onButtonPress.bind(this)}>
            <Text> Click Me </Text>
          </TouchableOpacity >
       <View>
    );
  }
}

Alternatively binding method in constructor will also work

class Demo extends Component {
  constructor(props){
    super(props);
    this.onButtonPress= this.onButtonPress.bind(this);
  }
  onButtonPress() {
    console.log("click");
  }

  render() {
    return (
        <View>
          <TouchableOpacity onPress={this.onButtonPress()}>
            <Text> Click Me </Text>
          </TouchableOpacity >
       <View>
    );
  }
}
Firdous nath
  • 1,487
  • 1
  • 14
  • 38
-2

I'm not sure if this will help but I write my functions this way and haven't encountered this problem.

If I were you I'd try binding the function in the place where you declare it.

 setModalVisible = (visible) => {
    this.setState({ youtubeModalVisible: visible });
 }

If you do this, you don't have to bind in the constructor.

constructor(props) {
    ...
    // Comment this out to see it will still bind.
    // this.setModalVisible = this.setModalVisible.bind(this);
    ...
}

Lastly, if this function will only set the modal's state to visible, you might want to remove the argument and pass it this way.

<TouchableOpacity style={styles.eachChannelViewStyle}  onPress={this.setModalVisible}>
  ...
</TouchableOpacity>

// Refactored function declaration would look like this
 setModalVisible = () => {
    this.setState({ youtubeModalVisible: true });
 }
PrimeTimeTran
  • 1,807
  • 2
  • 17
  • 29