gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:58:57 25 4
gpt4 key购买 nike

我在为 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);

我无法运行 something 功能。我尝试了各种语法但没有成功。问题似乎是 this 不是我期望的那样,并且它没有定义变量 something

我必须让它工作的唯一方法是在 AwesomeProject 类之外使用 var something = function(){...} 声明一个外部变量。

有没有办法在 AwesomeProject 中声明时访问 something?根据通量架构之类的,这可能是一种不好的做法吗?

最佳答案

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

问题在于,使用 ES6 语法时,您无法自动绑定(bind) this,因此您需要自己完成。

I've learned a bit more since I posted this answer. The real problem is that this is "bound" when the function is executed, not when it's declared. It points to the object the function is attached to when called. For example:

obj.foo(); //inside foo, this points to obj
bar(); //inside bar, this points to the global object (or undefined in strict mode)

In my example the function this.renderMovie() is passed as a parameter. So inside ListView it will be a "local variable". It will be called "detached" from any object, like the bar() example before, so this will not be what I expect.

It's possible to force the binding of this.

我的问题有 3 种可能的解决方案,我最喜欢第 3 种:

选项 1:在调用时手动绑定(bind)

在代码中,将对 {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:在构造函数上进行绑定(bind)

当然,绑定(bind)正确的函数:

  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
}

关于javascript - 如何在 ListView 的 renderRow 中访问 `this`?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36777607/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com