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

IT技术 javascript reactjs ecmascript-6 es6-class
2021-02-05 20:23:10
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}>

版本有何不同?或者这只是一个偏好问题?


谢谢大家的回答和评论。都是有帮助的,我强烈建议阅读此链接FIRST如果你是这个困惑了我。
http://blog.andrewray.me/react-es6-autobinding-and-createclass/

2个回答

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

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

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

预绑定到您的class

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

一个。在您的构造函数中进行绑定。又名

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

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

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

运行时绑定到您的类

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

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

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

这可以提供额外的功能,比如您是否需要为点击处理程序传递额外的数据<input onChange={(event) => { this.someEventHandler(event, 'username') }>也可以这样做bind

您可以.bind(this)按上述方式使用

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

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

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

在你的例子中

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

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

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

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

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

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

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

为什么要绑定 React 函数?

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

一般来说,如果你引用一个没有()在它后面的方法,比如onChange={this.someEventHandler},你应该绑定那个方法。

onChange函数绑定到正确上下文的三种方法

第一的

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

在这个中,我们bind显式地使用to 函数使 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
}

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

在构造函数绑定它

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


return <input onChange={this.someEventHandler}>

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

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