我正在开发一个本机应用程序,我试图让一些图像像一个按钮,这样当你按下它们时,它们会在控制台中打印一个语句。
我的代码是:
class ImageList extends Component {
componentWillMount(){
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2
});
this.dataSource = ds.cloneWithRows(this.props.images);
}
imageTouched(){
console.log('pressed');
}
renderRow(rowData){
const {uri} = rowData;
return(
<View style={{padding: 1, alignSelf: 'flex-start'}}>
<TouchableHighlight onPress={this.imageTouched}>
<Image style={styles.imageSize} source={{uri: uri}} />
</TouchableHighlight>
</View>
)
}
render() {
return (
<View>
<ListView
contentContainerStyle={styles.list}
dataSource={this.dataSource}
renderRow={this.renderRow}
/>
</View>
);
}
}
var styles = StyleSheet.create({
imageSize: {
//newWidth is the width of the device divided by 4.
//This is so that four images will display in each row.
width: newWidth,
height: newWidth,
padding: 2
},
list: {
flexDirection: 'row',
flexWrap: 'wrap'
}
});
当我运行它时没有错误但是当我触摸图像时没有任何反应。我检查了控制台但没有打印任何内容。
如何让每张图片充当按钮?
答案 0 :(得分:2)
与其他人提到的一样,问题是this
方法中没有约束renderRow()
。我认为解决此问题的最简单方法是将renderRow()
更改为箭头功能:
renderRow = (rowData) => {
const {uri} = rowData;
return (
<View style={{padding: 1, alignSelf: 'flex-start'}}>
<TouchableHighlight onPress={this.imageTouched}>
<Image style={styles.imageSize} source={{uri: uri}} />
</TouchableHighlight>
</View>
);
}
箭头函数在调用时始终将this
设置为其包含范围,因此现在this.imageTouched
将解析。
请注意,您不必对imageTouched()
- 函数或调用执行任何操作,因为它不引用this
。
PS。此语法取决于公共类字段,它是编写本文时标准的第2阶段提案(可能包含在内部React代码中)。此功能可以与React Native项目中默认启用的babel-plugin一起使用。
PS2。请注意,使用箭头函数声明方法而不是在调用中使用箭头函数将为每个组件实例创建一个方法实例,而不是每个渲染一个实例。这应该是非常好的性能。
答案 1 :(得分:0)
试试这个
<TouchableHighlight onPress={() => this.imageTouched()}>
确保绑定renderRow
renderRow={this.renderRow.bind(this)}
答案 2 :(得分:0)
定义为ES6类的React组件不会自动绑定方法&#39;组件实例的this
上下文。在这种特殊情况下,renderRow
回调未绑定,而上下文引用全局应用程序上下文,因此对this.imageTouched
的引用未定义。
您经常看到的一种常见模式是在渲染方法中绑定回调:
<ListView
renderRow={this.renderRow.bind(this)}
/>
但是,这会在每个渲染上创建一个新的函数实例,这会导致垃圾收集器不必要的工作。
另一种方法是使用(词法范围)箭头函数并明确调用方法:
<ListView
renderRow={(data) => this.renderRow(data);
/>
但这会产生不必要的效果,在每次渲染时都会不必要地创建函数。
稍微冗长,但更多&#34;正确&#34;方法是绑定类构造函数中的回调:
constructor(props) {
super(props);
this.renderRow = this.renderRow.bind(this);
}