调用ES6方法时绑定上下文。如何从内部方法访问对象,称为回调? [英] Binding context when calling ES6 method. How to access object from within method called as callback?

查看:132
本文介绍了调用ES6方法时绑定上下文。如何从内部方法访问对象,称为回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图围绕ES6中的Classes语法。在同一时间通过Bonnie Eisenman的学习反应本土学习Fabric。

I'm trying to wrap my head around the syntax for Classes in ES6. While at the same time learning Fabric native through Bonnie Eisenman's Learning React Native.

我已经遇到一个关于访问这个在回调中,当该回调是Class方法时。我知道围绕词汇的问题,这个在回调中已经在StackOverflow上提出了很多次。例如
如何访问正确回调中的这个内容?

I've come accross an issue around accessing this in a callback, when that callback is a Class "method". I'm aware issues around lexical this in callbacks have been raised many times on StackOverflow. For instance in How to access the correct `this` context inside a callback?.

根据我的在线研究,我遇到了一个解决方案。但是我不知道这是ES6中正确的方法。

Based on my research online I've come across a solution. But I am not sure this is the correct way to do it in ES6.

当我尝试以下内容时,我的问题出现了:

My issue came about when I tried the following below:

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
  }

  _handleTextChange(event) {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

  render() {
    return (
      <TextInput
        style={styles.input}
        onSubmitEditing={this._handleTextChange}/>
    );
  }
}

(我从示例中稍稍修改在书中匹配ES6类语法和导入/导出语法而不是Require。)

(Which I've only slightly modified from the example in the book to match the ES6 class syntax and the import/export syntax instead of Require.)

如果我这样做,这个 _handleTextChange 未定义(无法读取未定义的属性setState)。我很惊讶这个。来自其他OO语言,我正在解释,好像这个方法的行为更像是静态方法。

If I do this, the this in _handleTextChange is undefined (cannot read property 'setState' of undefined). I was surprised by this. Coming from other OO languages, I'm interpreting as though this method is behaving more as if it was a static method.

我已经能够通过跳过来解决这个问题类方法并使用箭头符号。 onSubmitEditing = {event => this.setState({name:event.nativeEvent.text})} 。哪个工作正常我没有任何问题或混淆。

I've been able to solve this by skipping the class method and using the arrow notation. onSubmitEditing={event => this.setState({name: event.nativeEvent.text})}. Which works fine. I have no problems or confusion with that.

我真的想解决如何调用类方法。经过一番研究,我已经设法通过执行以下操作使其工作: onSubmitEditing = {this._handleTextChange.bind(this)} 。也许我误解了JavaScript的一个基本方面(我是JS中的初学者),但这对我来说似乎是完全疯狂的。是否真的没有办法从一个方法内部访问一个对象的上下文,而没有明确地将对象绑定到...它是自己的方法,在它被调用的位置?

I really want to work out how to call a class method though. After a fair bit of research I've managed to make it work by doing the following: onSubmitEditing={this._handleTextChange.bind(this)}. Perhaps I've misunderstood a fundamental aspect of JavaScript (I'm a beginner in JS), but this seems completely insane to me. Is there really no way of accessing the context of an object from within a method without explicitly binding the object back onto... it's own method, at the point where it is called?

我还尝试在构造函数中添加 var self = this; ,并调用 self.setState code> _handleTextChange 。但是并没有太惊讶,发现没有工作。

I've also tried adding var self = this; in the constructor and calling self.setState in _handleTextChange. But wasn't too surprised to find that didn't work.

当被称为回调时,从一种方法访问对象的方法是什么? ?

What's the correct way of accessing an object from within one of its methods when it is called as a callback?

推荐答案

React.createClass(ES5)创建类的方式具有内置功能,将所有方法绑定到这个自动。但是在ES6中引入并迁移React.createClass时,他们发现对于其他类中不用于此功能的JavaScript开发人员来说,这可能会有点混乱,当他们从React转到其他课程时,会感到困惑。

React.createClass (ES5) way of creating class has a built-in feature that bound all methods to this automatically. But while introducing classes in ES6 and migrating React.createClass, They found it can be a little confusing for JavaScript developers that are not used to this feature in other classes, or it can be confusing when they move from React to other classes.

所以他们决定不将这个内置到React的类模型中。您仍然可以在构造函数中明确地预绑定方法,如果你想要

So, they decided not to have this built-in into React's class model. You can still explicitly prebind methods in your constructor if you want like

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
    this._handleTextChange = this._handleTextChange.bind(this); //Binding to `this`
  }

  _handleTextChange(event) {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

但是我们总是有一个简单的方法来避免这种预绑定。是啊!你说对了。箭头函数。

But we always have a simple way to avoid this prebinding. Yeah! You got it. Arrow functions.

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
  }

  _handleTextChange = event => {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

  render() {
    return (
      <TextInput
        style={styles.input}
        onSubmitEditing={this._handleTextChange}/>
    );
  }
}

BTW,这是关于React。 ES6类总是有一种从方法中访问对象的上下文的方式,而不会将对象重新绑定到自己的方法上。

BTW, This is all regarding React. ES6 class always has a way of accessing the context of an object from within a method without explicitly binding the object back onto it's own method.

class bindTesting {
  constructor() {
    this.demo = 'Check 1';
  }

  someMethod() {
    console.log(this.demo);
  }

  callMe() {
    this.someMethod();
  }
}

let x = new bindTesting();
x.callMe(); //Prints 'Check 1';

但是,如果我们在JSX Expression中调用它,则不会打印检查1。

But this doesn't prints 'Check 1' if we call it in JSX Expression.

EDIT :: As @Oka提到,类体中的箭头函数是ES7 +功能,可以在编译器/ polyfills(如babel)中使用。如果您不使用支持此功能的transpiler,我们可以如上所述绑定到这个,或者像这样写一个新的BaseComponent(这是一个坏主意) p>

EDIT :: As @Oka mentioned, arrow functions in class bodies is ES7+ feature and available in Compiler/polyfills like babel. If you're not using transpiler that support this feature, We can just bind to this as mentioned above or write a new BaseComponent like this ( Which is a bad idea )

class BaseComponent extends React.Component {
 _bind(...methods) {
  methods.forEach( (method) => this[method] = this[method].bind(this) );
 }
}

class ExampleComponent extends BaseComponent {
 constructor() {
  super();
  this._bind('_handleTextChange', '_handleClick');
 }
 // ...
}

这篇关于调用ES6方法时绑定上下文。如何从内部方法访问对象,称为回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆