我正试图了解ES6中类的语法.同时通过Bonnie Eisenman的学习React native学习布料的本族语.

我遇到了一个关于在回调中访问this的问题,当回调是一个类"方法"时.我知道,关于StackOverflow的回调中词汇this的问题已经被多次提出.比如在

根据我在网上的研究,我找到了一个解决方案.但我不确定在ES6中这样做是否正确.

当我try 以下方法时,出现了我的问题:

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.)

如果我这样做,_handleTextChange中的this是未定义的(无法读取未定义的属性'setState').我对此感到惊讶.来自其他OO语言,我解释这个方法的行为更像是一个静态方法.

我已经能够通过跳过类方法并使用箭头符号来解决这个问题.这很好用.我对此没有任何问题或困惑.

不过,我真的很想知道如何调用类方法.经过一段时间的研究,我成功地做到了以下几点:onSubmitEditing={this._handleTextChange.bind(this)}.也许我误解了JavaScript的一个基本方面(我是JS的初学者),但这在我看来完全是疯了.如果不显式地将对象绑定回方法中,是否真的无法从方法中访问对象的上下文...它是自己的方法,在调用它的地方?

我还try 在构造函数中添加var self = this;,并在_handleTextChange中调用self.setState.但发现这不起作用并不感到惊讶.

当对象作为回调调用时,从其方法中访问对象的正确方式是什么?

推荐答案

react createClass(ES5)创建类的方式有一个内置功能,可以自动将所有方法绑定到this.但在ES6中引入classes和迁移时.他们发现,对于其他类中不习惯此功能的JavaScript开发人员来说,createClass可能有点让人困惑,或者当他们从React转移到其他类时,可能会让人困惑.

因此,他们决定不在React的类模型中内置此功能.如果愿意,仍然可以在构造函数中显式地预绑定方法

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})
  }

但我们总是有一个简单的方法来避免这种预绑定.是 啊你明白了.箭头功能.

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}/>
    );
  }
}

顺便说一句,这都是关于react 的.ES6类总是有一种从方法中访问对象上下文的方法,而无需将对象显式绑定回它自己的方法.

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表达式中调用它,它不会打印"Check 1".

编辑::正如@Oka所提到的,类主体中的箭头函数是ES7+特性,可以在编译器/多填充中使用,比如babel.如果您不使用支持此功能的transpiler,我们可以像上面提到的那样绑定到this,或者像这样编写一个新的BaseComponent(这是个坏主意)

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');
 }
 // ...
}

React-native相关问答推荐

react 在顶部选项卡导航中传递本机数据

FlatList有时不会在数据更改时重新呈现

无法读取 @react-native-async-storage/async-storage 的未定义属性setItem

任务:react-native-async-storage_async-storage:generateReleaseRFile FAILED

如何修复 React Native 中任务:app:processDebugManifest的执行失败?

如何判断 Detox 正在运行测试?

React Native - Expo:fontFamily 'SimpleLineIcons' 不是系统字体,尚未通过 Font.loadAsync 加载

React-navigation:增加底部标签导航的高度?

Firebase JavaScript SDK 和 react-native-firebase 有什么区别

React-native 解码 base64 编码字符串

react-native - 如何在过go 两个文件夹中导入组件?

react-native android应用程序中的underlineColorAndroid is not a valid style property错误

如何在react-native中设置 FlatList 的刷新指示器?

为什么,确切地说,我们需要 React.forwardRef?

如何在 React Native 中将图像放置在其他图像之上?

开始滚动时使 TouchableOpacity 不突出显示元素

React Native:使用百分比时将视图的宽度设置为等于其高度

如何在react-native中将文本放置在图像上?

react-native 开始给出 Invalid 正则表达式无效错误

将 colored颜色 变量导入我的样式