且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-11-23 07:38:47

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

Binding is not something that is specifc to React, but rather how this works in 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).

什么时候绑定上下文取决于函数的目的,如果你需要访问类上的道具、状态或其他成员,那么你需要绑定它.

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.

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

.bind(this) is used to bind the this context to your components function. 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. 在您的构造函数中进行绑定.又名

a. in your constructor do the binding. aka

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

b. 在类胖箭头函数上制作您的自定义函数.又名

b. make your custom functions on the class fat arrow functions. aka

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

运行时绑定到您的类

几种常见的方法

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

a. you can wrap your components handler function with an inline lambda (fat arrow) function.

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

这可以提供额外的功能,比如如果你需要为点击处理程序传递额外的数据 ;{ this.someEventHandler(event, '用户名') }>.可以用 bind

this can provide additional functionality like if you need to pass additional data for the click handler <input onChange={(event) => { this.someEventHandler(event, 'username') }>. The same can be done with bind

b. 你可以使用 .bind(this) 如上所述.

b. you can use .bind(this) as described above.

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

带有附加参数

如果您想避免创建新的函数引用但仍需要传递参数,***将其抽象为子组件.您可以在此处阅读更多相关信息

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

// 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.