无法将方法的头部传递给 React 标记中的事件处理

Posted

技术标签:

【中文标题】无法将方法的头部传递给 React 标记中的事件处理【英文标题】:Can't pass a head of a method to event handling in React markup 【发布时间】:2019-02-27 06:06:01 【问题描述】:

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

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


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

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

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 的方法,事实上,当我调查 this 是,我发现它是 undefined

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

【问题讨论】:

你在constructor()绑定你的函数了吗? binding patterns 你可以 this.handleEmail(e) /> 而不是绑定它 @kiranvj 不,我没有。现在,正如您所说,我看到该部分已在所提供示例的构造函数中实现。它似乎有效,因此您可能希望将您的评论重新发布为回复,以便可以接受。尽管如此,语法 this.foo=this.foo.bind(this) 看起来还是很迟钝。如果 this 在那里,那么它应该在那里而不把它放在那里。我想这是我对 React 的无知在这里闪耀...... @LazarNikolic 您介意重新发布您的评论作为回复并填写一两行讨论不同绑定/非绑定方法的优缺点吗?它可能对后代有用(从我开始)。 【参考方案1】:

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

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

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

bind 就是这样做的

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

问题

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

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

这是因为你使用了 ES6 箭头函数()=&gt; 。这也称为胖箭头函数。

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

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

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

我建议阅读这篇出色的 article 以了解有关 bind 的更多详细信息

【讨论】:

【参考方案2】:

我认为你应该做的是

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

我认为你的 restate 方法不是undefined 的方法的原因是因为你的方法没有绑定到组件。为了让您的方法成为反应类的一部分,您需要将该方法绑定到该类。有几种方法可以做到这一点。在这样的类构造函数中:

 constructor(props) 
  super(props);
  this.handleEmail = this.handleEmail.bind(this);
 

或者在渲染函数内部,就像我上面展示的那样。第三是在类体内使用箭头函数,如下所示:

handleEmail = () => 
  // call this function from render 
  // and this.whatever in here works fine.
;

【讨论】:

以上是关于无法将方法的头部传递给 React 标记中的事件处理的主要内容,如果未能解决你的问题,请参考以下文章

React js onClick无法将值传递给方法

React Native Expo MapView - 将标记详细信息传递给扩展的底部视图

[react] 怎样将事件传递给子组件?

React:是不是可以将事件传递给底层 iframe?

Symfony 3 - 无法将 token_storage 传递给订阅者

将状态传递给 React/Redux 中的递归嵌套组件