UnClickAble TouchableHighlight

2019-08-17 08:51发布

问题:

I got this code

constructor(props){
    super(props);
    this.MyClick = this.MyClick.bind(this)
}
MyClick() {
  alert('ohoho')
};
AnyRequest = () => {
    if(this.state.Array.length > 0 && this.state.Loaded === true){
        return this.state.Array.map(function(Data){
            return(
              <View>
                <TouchableHighlight underlayColor="#ccc" onPress={this.MyClick}>
                    <Icon name="check" size={30} color="#2eb82e" />
                </TouchableHighlight>
              </View>

            );
        });
    }
};

I have no idea why it doesn't work. First when I used MyClick = () => instead of binding function in the constructor it was saying undefined is not an object. As soon as I bound my function in the constructor it doesn't show error anymore but it doesn't seem like a TouchableHighlight button. Even underlayColor doesn't work.

回答1:

Ok, so from the comments, we can conclude that this the TouchableHighlight is indeed clickable. It's just your syntax for onPress that is incorrect. This is a very common mistake for developers without much experience in binding and ES6 syntax. There are answers that cover this already so I won't go into depth on it. Instead, I'll point out the two common ways you can correct define onPress in React Native (there are also multiple existing answers for this but they are only partially related):

The onPress prop of TouchableHighlight expects a function to be passed to it. So whatever is between the { } needs to be a function. The first way to do this is with arrow syntax which I suspect you did incorrectly:

MyClick = () => {
  alert('ohoho')
};

// ... later on ...

<TouchableHighlight underlayColor="#ccc" onPress={this.MyClick}>
  <Icon name="check" size={30} color="#2eb82e" />
</TouchableHighlight>

Note the this. as it's needed to correctly reference the right variable.

The second way is to bind the method as you're doing but then actually call it in a function that you pass to onPress like so:

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

MyClick() {
  alert('ohoho');
};

// ... later on ...

<TouchableHighlight
  underlayColor="#ccc"
  onPress={() => {
    this.MyClick();
  }}
>
  <Icon name="check" size={30} color="#2eb82e" />
</TouchableHighlight>

Note how you are defining an arrow function inside the { } and then actually calling MyClick inside that function.

If you don't understand the difference or make many mistakes like this, then I suggest brushing up on ES6 and ES7 as that is almost a requirement for writing React Native code. There are many resources online to help with this.



回答2:

Finally I got it. Problem wasn't in onPress function but in map function. As soon as I was creating new function it created a new scope which means this wasn't referring to AnyRequest function anymore. Finally ES6 arrows fixed it.

constructor(props){
super(props);
this.MyClick = this.MyClick.bind(this)
}
MyClick() {
alert('ohoho')
};
AnyRequest = () => {
if(this.state.Array.length > 0 && this.state.Loaded === true){
    return this.state.Array.map((Data) => (
          <View>
            <TouchableHighlight underlayColor="#ccc" onPress={() => 
                this.MyClick();
            }}>
                <Icon name="check" size={30} color="#2eb82e" />
            </TouchableHighlight>
          </View>
        ));
      }
   };