3

handleButtonPress在这个示例 React 组件中,如何在消息映射中调用?

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})
  }

}

现在它正在抛出:undefined is not a function (evaluating 'this.handleButtonPress(message)'). 为什么呢?

4

1 回答 1

7

问题是除非明确告知,否则Array.prototype.map它不会绑定上下文。this从文档中:

如果一个thisArg参数被提供给map,它将在调用时传递给回调,用作它的 this 值。否则,该值undefined将被传递用作其 this 值。1

由于您从不指定this值,因此它是undefined,因此this绑定到 is 中的匿名onPress函数undefined。这会引发错误,因为没有handleButtonPress. undefined这意味着您需要将this上下文传递给map文档,并从文档中传递:

句法

arr.map(callback[, thisArg])

这将像这样应用:

{
    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.
}

this是传递给 时的类map。然后它将绑定到onPress的事件处理程序(匿名函数),然后正确调用。(注意:你可能应该在构造函数中绑定你的方法一次,因为如果你现在这样做,每次触发事件时都会创建一个新方法。)


1实际上,没有thisArg通过,this值是照常确定的。由于this在常规函数中是windowundefined在严格模式下,这是类的默认设置),this所以不是您认为的那样。

于 2016-10-17T00:38:06.237 回答