【问题标题】:JSX props should not use .bind() - how to avoid using bind?JSX 道具不应该使用 .bind() - 如何避免使用绑定?
【发布时间】:2018-06-15 18:01:30
【问题描述】:

我有一个容器,我需要更改显示表单或显示成功页面的 UI 表单。

容器有一个 state.showSuccess,我需要 MyFormModule 才能调用容器来改变状态。

以下代码有效,但我收到以下警告:

JSX 属性不应使用 .bind()

如何在不使用 .bind() 的情况下使其工作?

...
const myPage = class extends React.Component {
  state = { showSuccess: false };
  showSuccess() {
   this.setState({
      showSuccess: true,
    });
  }
  render() {
    const { showSuccess } = this.state;
    if (showSuccess) {...}
    ....
    <MyFormModule showSuccess={this.showSuccess.bind(this)} />

【问题讨论】:

  • 也许使用箭头函数?:showSuccess={() =&gt; this.showSuccess()}
  • @CRice 做到了,谢谢!请发布答案,以便我为您投票。
  • 如果你的 JSX 中不需要箭头函数,你也可以在构造函数中绑定它

标签: javascript reactjs components


【解决方案1】:

您应该首先understand WHY this is a bad practice

这里的主要原因是 .bind 正在返回一个新的函数引用。
这将在每个 render 调用上发生,这可能会导致性能下降。

你有两个选择:

  1. 使用构造函数来bind您的处理程序(这将只运行一次)。

    constructor(props) {
      super(props);
      this.showSuccess = this.showSuccess.bind(this);
    }
    
  2. 或者使用arrow functions 创建您的处理程序,以便他们使用 this 的词汇上下文,因此您不需要 bind 他们在 全部(you will need a babel plugin):

    showSuccess = () => {
      this.setState({
        showSuccess: true,
      });
    }
    

您应该使用这种模式(如其他人建议的那样):

showSuccess={() => this.showSuccess()}

因为这也会在每次渲染时创建一个新函数。
因此,您可以绕过警告,但您仍然在以不良实践设计编写代码。

来自ESLint docs

JSX 属性中的绑定调用或箭头函数将创建一个全新的 在每个渲染上都起作用。这对性能不利,因为它 将导致垃圾收集器被调用的方式比现在更多 必要的。如果一个全新的,它也可能导致不必要的重新渲染 函数作为道具传递给使用引用的组件 对 prop 进行相等性检查以确定它是否应该更新。

【讨论】:

  • 你说得对,这是一个潜在的性能问题(正如文档承认的那样),但总的来说,it's probably okay
  • 是的,如果 OP 有一个 linting 规则警告“JSX props should not use.bind()”,那么我们可能想解释为什么这个警告存在以及如何使代码更好而不是绕过规则:)
【解决方案2】:

使用箭头函数,因为它们会自动继承定义它们的位置的 this 上下文。

showSuccess={() => this.showSuccess()}

这里是关于这个主题的facebook documentation 的链接,其中列出了这种方法作为一种解决方案。有趣的是,他们还列出了在 props 中使用 .bind 作为解决方案之一,即使它在实际使用时会产生警告。

从该文档中,您会注意到这是一个潜在的性能问题,因为该函数将在每次渲染时重新创建:

注意:

在渲染中使用箭头函数每次都会创建一个新函数 组件渲染,这可能会影响性能(请参阅 下面)。

但也来自同一个链接:

可以在渲染方法中使用箭头函数吗?通常来说,一般来说, 是的,没关系,而且这通常是最简单的传递参数的方法 回调函数。

如果您确实遇到性能问题,请务必优化!

所以我想说,如果您的组件会非常频繁地重新渲染,您应该使用其他解决方案之一:在构造函数中绑定,或者首先使用箭头函数定义方法。但如果不是,请使用您认为最干净的任何方法。

【讨论】:

  • 这是同样的坏习惯。它将创建一个与.bind 相同的新函数实例。
  • 它是一个匿名函数,每次渲染都会创建它
  • 是的,如果 OP 有一个 linting 规则警告“JSX props should not use.bind()”,那么我们可能想解释为什么这个警告存在以及如何使代码更好而不是绕过规则:)
【解决方案3】:

定义 showSuccess 时使用箭头函数

showSuccess = () => {
  this.setState({
    showSuccess: true,
  });
} 

【讨论】:

    猜你喜欢
    • 2017-04-07
    • 2023-03-12
    • 2017-05-25
    • 2019-01-10
    • 2012-05-02
    • 2016-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多