JSX道具不应该使用.bind() - 如何避免使用bind?

时间:2018-01-05 21:55:24

标签: javascript reactjs components

我有一个容器,我需要更改显示表单或显示成功页面的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)} />

3 个答案:

答案 0 :(得分:10)

您应该先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,
      });
    }
    
  3. 你应该使用这种模式(正如其他人建议的那样):

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

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

    来自ESLint docs

      

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

答案 1 :(得分:1)

定义showSuccess时使用箭头功能

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

答案 2 :(得分:0)

使用箭头功能,因为它们会自动继承this上下文的任何位置。

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

以下是此主题的facebook documentation链接,其中列出了此方法作为解决方案。有趣的是,他们还使用道具中的.bind作为解决方案之一列出,即使它在实际使用时会产生警告。

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

  

注意:

     

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

但也来自同一个链接:

  

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

     

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

所以我想说如果你的组件会经常重新渲染,你应该使用其他解决方案之一:在构造函数中绑定,或者首先用箭头函数定义方法。但如果没有,请使用对您来说最干净的方法。