Method inside anonymous function inside map is undefined [duplicate]

点点圈 提交于 2019-12-24 02:04:01

问题


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 to map, it will be passed to callback when invoked, for use as its this value. Otherwise, the value undefined 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!