问题
How does one invoke handleButtonPress
inside the message map in this example React component?
import React, { Component } from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
export default class MyComponent extends Component {
constructor(props){
super(props)
this.state = {messages:["THANKS", "MERCI", "GRAZIE"]}
this.myFunc = this.myFunc.bind(this)
this.handleButtonPress = this.handleButtonPress.bind(this)
}
render(){
return (
<View>
<Text>{this.state.message}</Text>
{
this.state.messages.map(function(message, index){
return (
<TouchableOpacity key={index} onPress={function(){ this.handleButtonPress(message) }.bind(this) }>
<Text>Press Me</Text>
</TouchableOpacity>
)
})
}
</View>
)
}
handleButtonPress(message){
console.log("BUTTON WAS PRESSED WITH MESSAGE: " + message)
this.myFunc(message)
}
myFunc(message){
console.log("MY FUNCTION WAS CALLED")
this.setState({message:message})
}
}
Right now it's throwing: undefined is not a function (evaluating 'this.handleButtonPress(message)')
. Why is that so?
回答1:
The problem is that Array.prototype.map doesn't bind a this
context unless explicitly told to. From the documentation:
If a
thisArg
parameter is provided tomap
, it will be passed to callback when invoked, for use as its this value. Otherwise, the valueundefined
will be passed for use as its this value.1
Since you never specify a this
value, it is undefined
, and doing thus the this
that is bound to the anonymous function in onPress
is undefined
. That throws the error because there is no function handleButtonPress
of undefined
. This means you need to pass a this
context to map
, and from the documentation:
Syntax
arr.map(callback[, thisArg])
This will be applied like so:
{
this.state.messages.map(function(message, index){
return (
<TouchableOpacity key={index} onPress={function(){ this.handleButtonPress(message) }.bind(this) }>
<Text>Press Me</Text>
</TouchableOpacity>
)
}, this) //Notice the `this` here, this is the optional thisArg which is used as the `this` value in the callback.
}
The this
is the class when passed to map
. It will then be bound to onPress
's event handler (the anonymous function) and then call correctly. (Note: You should probably bind your methods once in the constructor because if you do it as you do now, a new method will be created every time the event is triggered.)
1Actually, without a thisArg
passed, the this
value is determined as usual. Since this
in regular functions is window
(undefined
in strict mode, which is default for classes), this
isn't what you think it is.
来源:https://stackoverflow.com/questions/40076995/method-inside-anonymous-function-inside-map-is-undefined