React中的this

来源:互联网 发布:哪种后缀的域名比较好 编辑:程序博客网 时间:2024/06/07 15:57

英语原文:https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

在React中至少有五种处理 this 上下文的方法。 让我们考虑每个方法的优缺点。

  1. React.createClass过时了, 不说了 嘿嘿嘿…

下面的方法都假定您通过ES6类声明了React组件。 如果您使用ES6类,则不再使用自动绑定。

  1. Bind in Render
    一种解决方法是在render中调用bind:
onChange={this.handleChange.bind(this)}

这种方法简洁明了,但由于 function函数 在每个render上重新分配,所以有性能影响。 这听起来是个大问题,但是在大多数应用程序中,这种方法的性能影响是不太可能引人注目的。
总之:
如果您遇到性能问题,请避免在render中使用bind或箭头函数。—链接:https://facebook.github.io/react/docs/components-and-props.html

  1. Use Arrow Function in Render

    您可以通过在render(渲染)中使用箭头函数来避免更改此上下文:

    onChange={e => this.handleChange(e)}

    这种方法与#2具有相同的潜在性能影响。
    方法#4值得考虑,因为它们提供卓越的性能,只需少量额外的成本。

  2. Bind in Constructor
    避免在render中绑定的一种方法是在构造函数中绑定(另一种方法在下面的#5中讨论)。

constructor(props) {  super(props);  this.handleChange = this.handleChange.bind(this);}

这是React文档中“更好的应用程序性能”中推荐的方法。链接-https://facebook.github.io/react/docs/components-and-props.html

这也是我在“建立ES6中的React and Redux应用程序”中使用的方法。

然而,在大多数应用程序中,方法#2和#3的性能影响并不明显,所以方法#2和#3的可读性和维护优势可能会超过许多应用程序的性能问题。

但是如果你愿意使用 stage-2 的特征,下面的最后一个选择可能是你最好的选择。

  1. Use Arrow Function in Class Property

这种技术依赖于 类属性特征。 要使用此方法,你必须在babel中启用 transform-class-properties 与 stage-2

handleChange = () => {  // call this function from render   // and this.whatever in here works fine.};

这种方法有多个优点:

  1. 箭头函数在 封闭作用域中 使用 bind绑定this,(换句话说,this不会随作用域改变而改变),所以事情只能自动工作。

它避免了方法#2和#3的性能问题。

它避免了方法4中的重复。

通过将相关函数转换为箭头函数,直接将ES5 createClass样式重构为此样式。 事实上,有一个完全自动化的方式来处理这个使用一个codemod。链接:https://github.com/reactjs/react-codemod#class

总结

有图有真像:

以下是所有5种方法的完整工作示例:

// Approach 1: Use React.createClassvar HelloWorld = React.createClass({  getInitialState() {    return { message: 'Hi' };  },  logMessage() {    // this magically works because React.createClass autobinds.    console.log(this.state.message);  },  render() {    return (      <input type="button" value="Log" onClick={this.logMessage} />    );  }});// Approach 2: Bind in Renderclass HelloWorld extends React.Component {  constructor(props) {    super(props);    this.state = { message: 'Hi' };  }  logMessage() {    // This works because of the bind in render below.    console.log(this.state.message);  }  render() {    return (      <input type="button" value="Log" onClick={this.logMessage.bind(this)} />    );  }}// Approach 3: Use Arrow Function in Renderclass HelloWorld extends React.Component {  constructor(props) {    super(props);    this.state = { message: 'Hi' };  }  logMessage() {    // This works because of the arrow function in render below.    console.log(this.state.message);  }  render() {    return (      <input type="button" value="Log" onClick={() => this.logMessage()} />    );  }}// Approach 4: Bind in Constructorclass HelloWorld extends React.Component {  constructor(props) {    super(props);    this.state = { message: 'Hi' };    this.logMessage = this.logMessage.bind(this);  }  logMessage() {    // This works because of the bind in the constructor above.    console.log(this.state.message);  }  render() {    return (      <input type="button" value="Log" onClick={this.logMessage} />    );  }}// Approach 5: Arrow Function in Class Propertyclass HelloWorld extends React.Component {  // Note that state is a property,  // so no constructor is needed in this case.  state = {    message: 'Hi'  };  logMessage = () => {    // This works because arrow funcs adopt the this binding of the enclosing scope.    console.log(this.state.message);  };  render() {    return (      <input type="button" value="Log" onClick={this.logMessage} />    );  }}