为什么和何时需要在React中绑定函数和事件处理程序?
为什么和何时需要在React中绑定函数和事件处理程序?
我看到了不同版本的------here------
部分。
// 1
return
// 2
return { this.someEventHandler(event) }}>
// 3
return
这些版本有什么不同呢?还是只是个人偏好的问题吗?
谢谢大家的回答和评论。所有的回答都很有帮助,如果你对这个问题和我一样感到困惑,我强烈建议你先阅读这个链接:http://blog.andrewray.me/react-es6-autobinding-and-createclass/
在JavaScript中,类方法默认情况下不会绑定this。这意味着如果在定义一个使用ES6类的组件时,事件处理程序作为类的方法存在,如果忘记绑定该方法并将其传递给onChange事件,当实际调用该函数时,this将为undefined。为了解决这个问题,我们需要绑定React函数和事件处理程序。
为什么需要绑定React函数和事件处理程序?因为在JavaScript中,默认情况下类方法不会自动绑定this。如果忘记绑定函数并将其传递给事件处理程序,this将为undefined,导致出现问题。为了解决这个问题,有三种方法可以绑定函数和事件处理程序。
第一种方法是使用bind显式绑定函数,将onChange事件作为参数传递给事件处理程序。也可以使用这种方式传递其他参数,例如state.value。代码如下:
return
第二种方法是使用ES6语法,使用箭头函数并将事件对象作为参数传递给事件处理程序。这种方法与.bind(this)相同,但还可以传递其他属性和事件。代码如下:
return { this.someEventHandler(event) }}>
第三种方法是使用箭头函数定义事件处理程序,箭头函数没有自己的this,会使用外部执行环境的this值。代码如下:
someEventHandler = () => { console.log(this); // 此时的this指向React组件的上下文 }
或者在构造函数中绑定事件处理程序。代码如下:
constructor(props) { super(props); this.someEventHandler = this.someEventHandler.bind(this); } return
这些方法可以解决在React中绑定函数和事件处理程序的问题。通过绑定,可以确保函数在调用时具有正确的上下文,避免出现undefined的情况。
为什么需要在React中绑定函数和事件处理程序?在JavaScript中,绑定不是React特有的,而是与this
在JavaScript中的工作方式有关。每个函数/块都有自己的上下文,对于函数来说,它更具体地取决于其调用方式。当添加ES6支持(类语法)时,React团队决定不绑定类上的自定义方法(即不是内置方法,如componentDidMount
)的this
。
你应该在什么时候绑定上下文取决于函数的目的,如果需要访问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) }
这样做可以提供额外的功能,比如如果你需要为点击处理程序传递附加数据<input onChange={(event) => { this.someEventHandler(event, 'username') }>
。使用bind
也可以实现相同的功能。
b. 你可以像上面描述的那样使用.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}>
你只是将函数作为回调函数传递,以在点击事件发生时触发,没有附加参数。确保预先绑定它!
总结一下,思考如何优化你的代码是很重要的,每种方法都有其实用性/目的,取决于你的需求。