为啥以及何时需要在 React 中绑定函数和事件处理程序?

Posted

技术标签:

【中文标题】为啥以及何时需要在 React 中绑定函数和事件处理程序?【英文标题】:Why and when do we need to bind functions and eventHandlers in React?为什么以及何时需要在 React 中绑定函数和事件处理程序? 【发布时间】:2017-04-28 01:59:38 【问题描述】:
class SomeClass extends Component
  someEventHandler(event)
  
  render()
    return <input onChange=------here------>
  

我看到了不同版本的------here------ 部分。

// 1
return <input onChange=this.someEventHandler.bind(this)>

// 2
return <input onChange=(event) =>  this.someEventHandler(event) >

// 3
return <input onChange=this.someEventHandler>

版本有何不同?还是只是偏好问题?


谢谢大家的回答和cmets。一切都很有帮助,如果您对此感到困惑,我强烈建议您FIRST阅读此链接。http://blog.andrewray.me/react-es6-autobinding-and-createclass/

【问题讨论】:

推荐阅读blog.andrewray.me/react-es6-autobinding-and-createclass 您知道.bind 的作用以及this 的工作原理吗? 还有the proposed bind operator ::。像这样使用:return &lt;input onChange=::this.someEventHandler /&gt;,与the appropriate Babel transform。 gist.github.com/fongandrew/f28245920a41788e084d77877e65f22f 建议阅读 【参考方案1】:

绑定不是 React 特有的东西,而是 thisjavascript 中的工作方式。每个函数/块都有自己的上下文,因为函数更具体到它的调用方式。在添加 ES6 支持(类语法)时,React 团队决定 this 不绑定到类上的自定义方法(也不是像 componentDidMount 这样的内置方法)。

什么时候应该绑定上下文取决于函数的用途,如果你需要访问类中的 props、state 或其他成员,那么你需要绑定它。

对于您的示例,每个都不同,这取决于您的组件的设置方式。

预绑定到你的类

.bind(this) 用于将 this 上下文绑定到您的组件函数。但是,它会在每个渲染周期返回一个新的函数引用!如果您不想绑定函数的每次使用(例如在点击处理程序中),您可以预先绑定函数。

a. 在您的构造函数中进行绑定。又名

class SomeClass extends Component
    constructor()
        super();
        this.someEventHandler = this.someEventHandler.bind(this);
    
    someEventHandler(event)
    
    ....
 

b. 在类胖箭头函数上创建自定义函数。又名

class SomeClass extends Component
    someEventHandler = (event) => 
    
    ....

运行时绑定到您的类

一些常见的方法来做到这一点

a.您可以使用内联 lambda(粗箭头)函数包装您的组件处理程序函数。

onChange= (event) => this.someEventHandler(event) 

这可以提供额外的功能,比如如果您需要为点击处理程序&lt;input onChange=(event) =&gt; this.someEventHandler(event, 'username') &gt; 传递额外的数据。 bind也可以这样做

b.您可以使用.bind(this),如上所述。

onChange= this.someEventHandler.bind(this) 

带有附加参数&lt;input onChange= this.someEventHandler.bind(this, 'username') &gt;

如果您想避免创建新的函数引用但仍需要传递参数,最好将其抽象为子组件。 You can read more about that here

在你的例子中

// 1
return <input onChange=this.someEventHandler.bind(this)>

这只是将运行时事件处理程序绑定到您的类。

// 2
return <input onChange=(event) => this.someEventHandler(event) >

另一个运行时绑定到您的类。

// 3
return <input onChange=this.someEventHandler>

您只是将函数作为回调函数传递,以在点击事件发生时触发,没有额外的参数。一定要预先绑定!

总结一下。考虑如何优化代码很好,每种方法都有一个实用程序/用途,具体取决于您的需要。

【讨论】:

【参考方案2】:

为什么要绑定一个 React 函数?

当您使用 ES6 类定义组件时,常见的模式是事件处理程序成为类的方法。在 JavaScript 中,默认情况下不绑定类方法。如果您忘记将bind this.someEventHandler 传递给onChange,则在实际调用该函数时这将是未定义的。

一般情况下,如果你引用的方法后面没有(),比如onChange=this.someEventHandler,你应该绑定那个方法。

有三种方法可以将您的 onChange 函数绑定到正确的上下文

第一

return <input onChange=this.someEventHandler.bind(this)>

在这一个中,我们显式地使用bind 来使 onChange 事件作为 eventHandler 的参数可用。我们还可以发送一些其他参数,其语法类型为

return <input onChange=this.someEventHandler.bind(this, state.value)>

第二

return <input onChange=(event) =>  this.someEventHandler(event) >

这是一种 ES6 语法,我们可以指定要传递给someEventHandler 函数的参数。这相当于.bind(this) 但是,它也让我们可以灵活地发送其他属性以及事件,例如

return <input onChange=(event, value) =>  this.someEventHandler(event, value) >

第三

使用箭头函数定义函数 someEventHandler

someEventHandler = () => 
    console.log(this); // now this refers to context of React component

arrow function 没有自己的this,使用封闭执行上下文的this 值,因此上述函数得到正确的上下文。

在构造函数中绑定类似

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



return <input onChange=this.someEventHandler>

在此方法中,事件直接附加到someEventHandler 函数。这种方式不能传递其他参数

【讨论】:

@JohnRuddell 我没明白你的意思。也许我错过了什么。你能解释一下吗 好的,所以基本上.bind(this) 只是传递 context 并且与传递的参数无关。例如,如果我这样做onClick=this.someEventHandler.bind(this),那么处理函数会将我的上下文传递给它(又名this),但也会将事件作为第一个参数传递给它。所以...someEventHandler(event) console.log(event) 将是输入元素上的点击事件。 .bind(this) 只是在那个函数中让你的 this context 是类上下文 @ShubhamKhatri 当你说“在 JavaScript 中,默认情况下不绑定类方法”是什么意思?

以上是关于为啥以及何时需要在 React 中绑定函数和事件处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥以及何时使用重组分支?

react之事件处理

react事件绑定的三种常见方式以及解决Cannot update during an existing state transition (such as within `render`). Ren

React --绑定函数事件

React 实现数据双向绑定 事件的绑定以及传参 获取表单值的两种方法

react 框架中 事件的处理和绑定