JSX props不应使用 .bind() - 如何避免使用绑定?

IT技术 javascript reactjs components
2021-04-28 10:47:26

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

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

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

JSX props不应该使用 .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)} />
3个回答

您应该首先了解为什么这是一种不好的做法

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

你有两个选择:

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

    constructor(props) {
      super(props);
      this.showSuccess = this.showSuccess.bind(this);
    }
    
  2. 或者使用箭头函数创建处理程序,以便它们将使用词法上下文 for this,因此您根本不需要bind它们(您将需要一个 babel 插件):

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

你应该使用这种模式(如其他建议):

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

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

ESLint 文档

JSX props中的绑定调用或箭头函数将在每次渲染时创建一个全新的函数。这对性能不利,因为它会导致垃圾收集器被调用的方式超出必要的范围。如果一个全新的函数作为一个 prop 传递给一个组件,该组件使用对 prop 的引用相等性检查来确定它是否应该更新,它也可能导致不必要的重新渲染。

定义 showSuccess 时使用箭头函数

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

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

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

这是有关此主题facebook 文档的链接,其中列出了此方法作为解决方案。有趣的是,他们还将 using .bindin the prop 列为解决方案之一,即使它在实际使用时会产生警告。

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

笔记:

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

但也来自同一个链接:

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

如果您确实有性能问题,请务必进行优化!

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