简体   繁体   English

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

[英]Why and when do we need to bind functions and eventHandlers in React?

class SomeClass extends Component{
  someEventHandler(event){
  }
  render(){
    return <input onChange={------here------}>
  }
}

I see different versions of ------here------ part.我看到------here------部分的不同版本。

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

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

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

How are the versions different?版本有何不同? Or is it just a matter of preference?或者这只是一个偏好问题?


Thank you all for answers and comments.谢谢大家的回答和评论。 All are helpful, and I strongly recommend to read this link FIRST if you are confused as me about this.都是有帮助的,我强烈建议,如果你是这个困惑,我第一次读到这个链接。
http://blog.andrewray.me/react-es6-autobinding-and-createclass/ http://blog.andrewray.me/react-es6-autobinding-and-createclass/

Why bind a React function?为什么要绑定 React 函数?

When you define a component using an ES6 class, a common pattern is for an event handler to be a method on the class.当您使用 ES6 类定义组件时,常见的模式是将事件处理程序作为类上的方法。 In JavaScript, class methods are not bound by default.在 JavaScript 中,默认情况下不绑定类方法。 If you forget to bind this.someEventHandler and pass it to onChange , this will be undefined when the function is actually called.如果忘记bind this.someEventHandler并将其传递给onChange ,则实际调用该函数时 this 将是未定义的。

Generally, if you refer to a method without () after it, such as onChange={this.someEventHandler} , you should bind that method.一般来说,如果你引用一个没有()的方法,比如onChange={this.someEventHandler} ,你应该绑定那个方法。

There three ways to bind your onChange function to the correct contextonChange函数绑定到正确上下文的三种方法

First第一的

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

In this one we make use of bind explicitly to function to make the onChange event available as an argument to the eventHandler.在这个例子中,我们显式地使用bind to function 使 onChange 事件可用作 eventHandler 的参数。 We can also send some other parameter with type of syntax like我们还可以发送一些其他具有语法类型的参数,例如

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

Second第二

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

This is a ES6 syntax, whereby we can specifythe parameters that we want to pass to the someEventHandler function.这是 ES6 语法,我们可以通过它指定要传递给someEventHandler函数的参数。 This is equivalent to .bind(this) however, It also gives us the flexibility to send other attributes along with the event like这等效于.bind(this)但是,它还使我们可以灵活地将其他属性与事件一起发送,例如

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

Third第三

Define the function someEventHandler using Arrow function使用箭头函数定义函数 someEventHandler

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

An arrow function does not have its own this , the this value of the enclosing execution context is used and hence the above function gets the correct context. arrow function没有自己的this ,使用封闭执行上下文的this值,因此上述函数获得正确的上下文。

or bind it in constructor like将其绑定在构造函数中

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


return <input onChange={this.someEventHandler}>

In this method, event is directly attached to the someEventHandler function.在此方法中,事件直接附加到someEventHandler函数。 No other parameters can be passed this way不能通过这种方式传递其他参数

Binding is not something that is specifc to React, but rather how this works in Javascript.绑定是不是就是specifc反应,而是如何this工作在Javascript。 Every function / block has its own context, for functions its more specific to how its called.每个函数/块都有自己的上下文,对于函数来说,它更具体地取决于它的调用方式。 The React team made a decision for this to not be bound on custom methods on the class (aka not the builtin methods like componentDidMount ), when adding ES6 support (class syntax).该阵营团队做出了一个决定为this不被上的类(又名不是内建的方法,如自定义方法结合componentDidMount ),加入ES6支持时(类语法)。

When you should bind the context depends on the functions purpose, if you need to access props, state or other members on the class, then you would need to bind it.什么时候绑定上下文取决于函数的目的,如果你需要访问类上的道具、状态或其他成员,那么你需要绑定它。

For your example, each is different and it depends on how your component is set up.对于您的示例,每个都不同,这取决于您的组件的设置方式。

Pre binding to your class预绑定到您的班级

.bind(this) is used to bind the this context to your components function. .bind(this)用于将 this 上下文绑定到您的组件函数。 However, it returns a new function reference each render cycle!但是,它会在每个渲染周期返回一个新的函数引用! If you don't want to bind on each usage of the function (like in a click handler) you can pre-bind the function.如果您不想绑定函数的每次使用(例如在单击处理程序中),您可以预先绑定函数。

a.一种。 in your constructor do the binding.在您的构造函数中进行绑定。 aka又名

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

b.make your custom functions on the class fat arrow functions.在类胖箭头函数上创建自定义函数。 aka又名

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

Runtime binding to your class运行时绑定到您的类

few common ways to do this一些常见的方法来做到这一点

a.一种。 you can wrap your components handler function with an inline lambda (fat arrow) function.您可以使用内联 lambda(粗箭头)函数包装组件处理程序函数。

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

this can provide additional functionality like if you need to pass additional data for the click handler <input onChange={(event) => { this.someEventHandler(event, 'username') }> .这可以提供额外的功能,比如你是否需要为点击处理程序传递额外的数据<input onChange={(event) => { this.someEventHandler(event, 'username') }> The same can be done with bind使用bind也可以做到同样的事情

b.you can use .bind(this) as described above.您可以使用.bind(this)如上所述。

onChange={ this.someEventHandler.bind(this) }

with additional params <input onChange={ this.someEventHandler.bind(this, 'username') }>附加参数<input onChange={ this.someEventHandler.bind(this, 'username') }>

If you want to avoid creating a new function reference but still need to pass a parameter, its best to abstract that to a child component.如果您想避免创建新的函数引用但仍需要传递参数,最好将其抽象为子组件。 You can read more about that here你可以在这里阅读更多相关信息

In your examples在你的例子中

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

This is just doing a runtime event handler bind to your class.这只是将运行时事件处理程序绑定到您的类。

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

Another runtime bind to your class.另一个运行时绑定到您的类。

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

You are just passing the function as the callback function to trigger when the click event happens, with no additional parameters.您只是将该函数作为回调函数传递以在单击事件发生时触发,没有其他参数。 Make sure to prebind it!一定要预先绑定!

To summarize.总结一下。 Its good to think about how to optimize your code, each method has a utility / purpose depending on what you need.考虑如何优化您的代码很好,每种方法都有一个实用程序/目的,具体取决于您的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM