在事件处理程序中调用方法未定义

Invoking method inside event handler is undefined

本文关键字:方法 未定义 调用 事件处理 程序      更新时间:2023-09-26

以下示例中,当不需要任何参数时,handleButtonPress函数正常工作…

import React, { Component } from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
export default class MyComponent extends Component {
  constructor(props){
    super(props)
    this.state = {message:"HELLO"}
    this.myFunc = this.myFunc.bind(this)
    this.handleButtonPress = this.handleButtonPress.bind(this)
  }
  render(){
    return (
      <View>
        <Text>{this.state.message}</Text>
        <TouchableOpacity onPress={this.handleButtonPress}>
          <Text>Press Me</Text>
        </TouchableOpacity>
      </View>
    )
  }
  handleButtonPress(){
    console.log("BUTTON WAS PRESSED")
    this.myFunc()
  }
  myFunc(){
    console.log("MY FUNCTION WAS CALLED")
    this.setState({message:"GOODBYE"})
  }
}

,但在需要参数时不起作用:

render(){
    return (
      <View>
        <Text>{this.state.message}</Text>
        <TouchableOpacity onPress={function(){ this.handleButtonPress("GOODBYE") }}>
          <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("GOODBYE")')

我一直在使用的一个策略是在render函数中再次引用handleButtonPress函数,如下所示:

render(){
    handlePress = this.handleButtonPress;
    return (
      <View>
        <Text>{this.state.message}</Text>
        <TouchableOpacity onPress={function(){ handlePress("GOODBYE") }}>
          <Text>Press Me</Text>
        </TouchableOpacity>
      </View>
    )
  }

但是有其他/更好的方法吗?

因为有一个匿名函数,所以里面的this上下文是全局window对象。由于没有handleButtonPress存在,它抛出undefined不是函数的错误。您的解决方法有效,因为this仍然引用匿名函数之外的类,因此允许您将其引用分配给handlePress并调用它。

为了解决这个问题,可以使用Function.prototype.bind,它将为函数补充this上下文。从文档链接:

bind()方法创建了一个新函数,当调用该函数时,将其this关键字设置为提供的值…

你可以在这里像这样应用:

<TouchableOpacity onPress={function() { this.handleButtonPress("GOODBYE") }.bind(this)}>

这将把匿名函数的this上下文设置为类,而不是全局window对象,从而允许您调用this.handleButtonPress。然后可以按照文档中提到的再次压缩上述内容:

bind()方法创建一个新函数,当调用该函数时,将其this关键字设置为所提供的值,在调用新函数时所提供的任何参数之前具有给定的参数序列。(强调我的)

语法

fun.bind(thisArg[, arg1[, arg2[, ...]]])

其中arg1, arg2等是bind的可选参数,可以绑定到函数。可以这样应用:

<TouchableOpacity onPress={this.handleButtonPress.bind(this, "GOODBYE")}>

这完全摆脱了匿名函数,但是this仍然必须在bind中传递,因为您在handleButtonPress方法中使用它。