map中的匿名函数内部的方法是未定义的

s2t*_*2t2 2 javascript reactjs react-native es6-class

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

}
Run Code Online (Sandbox Code Playgroud)

现在它扔了:undefined is not a function (evaluating 'this.handleButtonPress(message)').为什么会这样?

Li3*_*357 6

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

如果thisArg提供了一个参数map,它将在调用时传递给回调,以用作其值.否则,undefined将传递该值以用作其此值.1

因为你从来没有指定this值,它是undefined,这样做this绑定匿名函数onPressundefined.这引发错误,因为没有功能handleButtonPressundefined.这意味着你需要传递一个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.
}
Run Code Online (Sandbox Code Playgroud)

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


1实际上,没有thisArg通过,该this值将照常确定.因为this在常规函数中window(undefined在严格模式下,这是类的默认模式),this不是你认为的那样.