为啥以及何时需要在 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 <input onChange=::this.someEventHandler />
,与the appropriate Babel transform。
gist.github.com/fongandrew/f28245920a41788e084d77877e65f22f 建议阅读
【参考方案1】:
绑定不是 React 特有的东西,而是 this
在 javascript 中的工作方式。每个函数/块都有自己的上下文,因为函数更具体到它的调用方式。在添加 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)
这可以提供额外的功能,比如如果您需要为点击处理程序<input onChange=(event) => this.someEventHandler(event, 'username') >
传递额外的数据。 bind
也可以这样做
b.您可以使用.bind(this)
,如上所述。
onChange= this.someEventHandler.bind(this)
带有附加参数<input onChange= this.someEventHandler.bind(this, 'username') >
如果您想避免创建新的函数引用但仍需要传递参数,最好将其抽象为子组件。 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事件绑定的三种常见方式以及解决Cannot update during an existing state transition (such as within `render`). Ren