首页 > 解决方案 > 无法将方法的头部传递给 React 标记中的事件处理

问题描述

在我的render()中,我有以下带有事件处理的组件。

render() { ...
  <input type="text" 
         onChange={(_) => { this.restate("email", _.target.value); }} />
}

private restate(type: string, input: any) { ...
  if (type === "email")
    this.setState({ ... });
}

这可以正常工作并按预期运行。因为我现在正在学习 React,所以我尝试改进我的语法,让它看起来很流畅。我找到了这个答案,并且喜欢事件处理程序分配的简洁性。所以我改变了我的渲染并实现了要传递的处理程序,如下所示。

render() { ...
  <input type="text" onChange={ this.handleEmail } />
}

private handleEmail(data: React.ChangeEvent<HTMLInputElement>) {
  console.log("hit before: " + data.target.value);
  console.log(this);
  this.restate("email", data.target.value);
}

标记的更改似乎有效,因为调用了方法handleEmail(...)。但是,我收到一个错误,说restate(...)不是undefined的方法,事实上,当我调查是什么时,我发现它是undefined

我需要帮助了解我做错了什么以及它与上面链接的文章有何不同。我试图用谷歌搜索 React 版本之间的语法差异,但一无所获。而且我不确定如何用正确的技术术语来描述这个问题。

标签: javascriptreactjstypescripteventsevent-handling

解决方案


为了this在 onClick 函数中使用,您需要在构造函数中绑定它。您也可以使用 bind in render(),但不建议这样做,因为bind会被多次调用。反应文档建议使用bind这样的内部构造函数

constructor() {
  super(); 
  this.handleEmail = this.handleEmail.bind(this);
}

这不是 React 特有的东西,它的 JavaScript。它的设计。

这是bind什么

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

问题

为什么你的第一个例子有效?

render() { ...
  <input type="text" 
         onChange={(_) => { this.restate("email", _.target.value); }} />
}

这是因为您使用了 ES6 箭头函数()=> {}。这也称为胖箭头函数。

每当您使用箭头函数时,this都会从周围的上下文中捕获,您可以this在函数内部使用而无需绑定。这就是为什么您的第一个示例有效的原因。

如果您像这样使用,您的第二个示例会起作用

render() { ...
  <input type="text" onChange={ ()=> this.handleEmail() } />
}

我建议阅读这篇优秀的文章以获取更多详细信息bind


推荐阅读