Intereting Posts
OpenGL на Android против iOS: оптимизация и где они отличаются RTSP через потоковое видео HTTPS от GStreamer EventBus, регистр и registerSticky метод Неразрешенная ошибка включения при использовании NDK Обнаружение ограниченного сетевого подключения в Android? Paypal payment: Как получить запрос успеха при загрузке PayPal в webview Android ViewPager Пред. / Следующая кнопка Обращайтесь с GoogleFit в фоновом режиме в приложении для Android Измените цвет стрелки на onProgressChanged Когда использовать библиотеку поддержки Белое пространство добавляется снизу, когда я помещаю Webview внутри scrollview в android Как я могу поделиться экраном на другой базе устройств с прямым соединением WiFi Как установить текущую временную метку для каждой строки вставки и обновления в андроиде realm Как изменить направление выделения текста TextView Как получить идентификатор файла, чтобы я мог выполнить загрузку файла из Google Диска API на Android

Как получить доступ к `this` внутри renderRow ListView?

У меня возникли проблемы с запуском функции для события onPress внутри строки ListView . Я следую инструкциям 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); - /** * 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); 

Я не могу запустить что- something функцию. Я пробовал различный синтаксис без успеха. Проблема заключается в том, что this не то, что я ожидаю, и она не имеет определенной переменной.

Единственный способ заставить его работать – объявить внешнюю переменную с var something = function(){...} вне класса AwesomeProject.

Есть ли способ получить доступ к something то, будучи объявленным внутри AwesomeProject ? Возможно, это плохая практика в соответствии с архитектурой потока или чем-то еще?

Solutions Collecting From Web of "Как получить доступ к `this` внутри renderRow ListView?"

Оказывается, я нашел решение самостоятельно, здесь: https://github.com/goatslacker/alt/issues/283#issuecomment-115391700

Проблема в том, что с синтаксисом ES6 у вас нет автообнаружения, поэтому вам нужно сделать это самостоятельно.

Есть 3 возможных решения моей проблемы, и мне нравится, 3-й из лучших:

Вариант 1: вручную связать это по вызову

В коде замените рефери на {this.renderMovie} whith {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: привязка к конструктору

И, конечно, свяжите правильную функцию:

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

Будьте осторожны, это просто предложение , а не стандарт!