如何在ListView的renderRow中访问`this`?

我无法在ListView的一行内的onPress事件中运行一个函数。 我正在遵循React Native教程试图从那里继续。 它似乎是使用ES6语法风格。

这是代码的相关部分。

 /** * Sample React Native App * https://github.com/facebook/react-native */ import React, { TouchableHighlight, AppRegistry, Component, Image, ListView, StyleSheet, Text, View, Alert, } from 'react-native'; class AwesomeProject extends Component { constructor(props) { super(props); this.something = this.something.bind(this); // <-- Trying this, not even sure why this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; } // //Irrelevant code here. Fetching stuff and renderLoadingView // something = function(){ console.log('something'); Alert.alert( 'Alert Title', 'alertMessage', ); } render() { console.log('this', this); //this is an instance of AwesomeProject if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie} style={styles.listView} /> ); } renderMovie(movie) { console.log('Not this', this); //this is not an instance of AwesomeProject return ( <TouchableHighlight onPress={() => {console.log(this); this.something()}}> <View style={styles.container}> <Image source={{uri: movie.posters.thumbnail}} style={styles.thumbnail} /> <View style={styles.rightContainer}> <Text style={styles.title} >{movie.title}</Text> <Text style={styles.year}>{movie.year}</Text> </View> </View> </TouchableHighlight> ); } } // //More irrelevant code here. Styles and the // AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject); 

我无法运行somethingfunction。 我已经尝试了各种语法没有成功。 问题似乎是, this不是我所期望的,也没有定义variables。

我必须做的唯一方法就是在AwesomeProject类之外声明一个外部variablesvar something = function(){...}

AwesomeProject中声明的时候有什么方法可以访问吗? 这可能是一个不好的做法,根据stream量架构或什么?

Solutions Collecting From Web of "如何在ListView的renderRow中访问`this`?"

原来,我自己find了解决scheme,在这里: https : //github.com/goatslacker/alt/issues/283#issuecomment-115391700

问题是使用ES6语法你没有自动绑定this ,所以你需要自己做。

有三个可能的解决scheme来解决我的问题,我喜欢第三个最好的:

选项1:手动绑定此通话

在代码中,将{this.renderMovie}replace为{this.renderMovie} {this.renderMovie.bind(this)}

  render() { console.log('this', this); //this is an instance of AwesomeProject if (!this.state.loaded) { return this.renderLoadingView(); } return ( <ListView dataSource={this.state.dataSource} renderRow={this.renderMovie.bind(this)} //<-- change here style={styles.listView} /> ); } 

选项2:在构造函数上进行绑定

当然,绑定正确的function:

  constructor(props) { super(props); this.something = this.something.bind(this); // <-- Not this function this.renderMovie = this.renderMovie.bind(this); // <-- This function!! this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }), loaded: false, }; } 

选项3:使用箭头语法,让他们做这项工作

我喜欢这个最好的。 你只需要使用箭头语法声明所涉及的函数,所以:

  renderMovie(movie) { //code here } 

变成这样:

  renderMovie = (movie) => { //code here } 

除了https://stackoverflow.com/a/36779517/6100821

选项4:使用绑定运算符

 <ListView dataSource={this.state.dataSource} renderRow={::this.renderMovie} //<-- cleaner, than bind style={styles.listView} /> 

小心,这只是一个build议 ,而不是一个标准!