使用 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,还有别的方式吗?

[react] 在React中什么时候使用箭头函数更方便呢?

无法在 React 组件类中使用箭头函数 [重复]