无法将方法的头部传递给 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 箭头函数()=>
。这也称为胖箭头函数。
每当您使用箭头函数时,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 Native Expo MapView - 将标记详细信息传递给扩展的底部视图