使用 React 时,在构造函数中使用粗箭头函数还是绑定函数更可取?
Posted
技术标签:
【中文标题】使用 React 时,在构造函数中使用粗箭头函数还是绑定函数更可取?【英文标题】:When using React Is it preferable to use fat arrow functions or bind functions in constructor? 【发布时间】:2017-05-13 21:33:00 【问题描述】:在创建 React 类时,哪个更可取?
export default class Foo extends React.Component
constructor (props)
super(props)
this.doSomething = this.doSomething.bind(this)
doSomething () ...
或
export default class Foo extends React.Component
doSomething = () => ...
我的一个同事认为后者会导致内存问题,因为 babel 将代码转换为在闭包内捕获 this
,并且该引用将导致实例不被 GC 清理。
对此有什么想法吗?
【问题讨论】:
Babel 对=>
函数所做的与 .bind()
所做的有何不同?
使用粗箭头函数将其保存在闭包中
是的。你认为.bind()
做了什么?
我正在查看转译后的代码,它看起来完全一样,但我不确定它在做什么
重点是,必须将this
的上下文值保存在某处。在.bind()
成为语言的一部分之前,它通常是通过闭包实现的,没有理由怀疑它现在基本上不一样了(尽管增加了一些行为)。
【参考方案1】:
这里的链接清楚地强调了官方说“在构造函数中绑定方法”是安全的,而不是使用箭头函数作为短代码来实现事件绑定。
这里是链接:https://reactjs.org/docs/react-without-es6.html#autobinding 供参考。
【讨论】:
【参考方案2】:公共类字段语法(所以doSomething = () => ...
)是not yet part of ECMAScript,但它做得很好,我很有信心它会到达那里。
所以使用这种语法会强制你进行转译,但它带来了好处:
表达this
绑定的清晰、简洁的语法
浏览器何时支持此功能的未来证明
不关心实施
对我来说,这是一个明显的胜利。在大多数情况下,您甚至不需要 constructor(props)
,从而使您免于使用样板文件 super
调用。
如果 Babel 实现会导致内存泄漏,您可以确定这些问题会很快被发现并修复。不得不编写更多代码,您更有可能自己造成泄漏。
【讨论】:
箭头函数是 ES2015 规范的一部分。 @Pointy 是的,但是公共类字段不是……【参考方案3】:render 函数中的绑定会导致在每次渲染时创建新函数,这意味着 diffing 算法认为有变化。当您在构造函数中绑定时,这不会发生。
这里你可以看到用箭头绑定和在构造函数中绑定的编译差异: https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&experimental=true&loose=false&spec=false&code=class%20x%20extends%20React.Component%20%7B%0A%20%20constructor%20(props)%20%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20%0A%20%20%20%20this.onChange%20%3D%20this.onChange.bind(this)%3B%0A%20%20%7D%0A%20%20%0A%20%20onChange%20()%20%7B%20console.log(%27change%20x%27)%3B%20%7D%0A%7D%0A%0Aclass%20y%20extends%20React.Component%20%7B%0A%20%20onChange%20%3D%20()%20%3D%3E%20%7B%20console.log(%27change%20y%27)%3B%20%7D%0A%7D
【讨论】:
我不是在询问渲染中的绑定,我是在询问在构造函数中使用粗箭头与绑定 这实际上是有价值的信息,我不明白为什么它被否决了。 这是正确答案。根据我的经验,使用胖箭头函数可能会导致内存泄漏,表现为分离的 DOM 节点。更好看,但这里有很大的内存成本。以上是关于使用 React 时,在构造函数中使用粗箭头函数还是绑定函数更可取?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不重新绑定 this 的情况下返回一个带有粗箭头函数的对象? [复制]
箭头函数“this”绑定在 React 组件中不起作用 [重复]
升级到 React Native 26 后使用箭头函数时不再绑定
[react] react中除了在构造函数中绑定this,还有别的方式吗?