[英]React Native ref in Flatlist items. Returning for last item alone
我正在使用react native flatlist组件创建可折叠列表。
我正在使用ref属性来单击该项目。
但是,当我尝试从click事件访问ref时,它不会对单击的项目起作用,而是对平面列表中的最后一个项目起作用。
export default class Update extends Component {
renderItems (data, index) {
return (
<TouchableNativeFeedback
onPress={() => this.expandView()}
>
<View style={[styles.itemWrapperExpandable]}>
<View style={styles.itemHeader}>
<View style={styles.itemAvatar}>
<Image source={require('../images/logo.png')} style={styles.avatar}></Image>
</View>
<View style={styles.itemContent}>
<Text style={[styles.itemTitle, styles.black]}>{data.name}</Text>
<Text style={[styles.rating, styles.grey]}>
{data.rating}<Icon name="star"></Icon>
</Text>
<Text style={[styles.content, styles.black]}>{data.description}</Text>
</View>
<View style={styles.itemBtn}>
<Icon name="chevron-down" style={{ color: '#000', fontSize: 22 }}></Icon>
</View>
</View>
<View ref={(e) => this._expandableView = e } style={[styles.itemBody]}>
<Text style={styles.itemBodyText}>
some more information about this update will appear here
some more information about this update will appear here
</Text>
</View>
</View>
</TouchableNativeFeedback>
);
}
expandView () {
LayoutAnimation.easeInEaseOut();
if (this._expandableView !== null) {
if (!this.state.isExpanded) {
// alert(this.state.isExpanded)
this._expandableView.setNativeProps({
style: {height: null, paddingTop: 15, paddingBottom: 15,}
})
}
else {
this._expandableView.setNativeProps({
style: {height: 0, paddingTop: 0, paddingBottom: 0,}
});
}
this._expandableView.setState(prevState => ({
isExpanded: !prevState
}));
}
}
render() {
return (
<FlatList
data={this.state.data}
renderItem={({ item, index }) => this.renderItems(item, index)}
/>
)
}
}
我还尝试使用项目的索引进行放置,但无法使其正常工作。
可以解决吗? 我认为在渲染项目时,下一个参考将覆盖该参考。
您的假设是正确的。 参考被下一项覆盖,因此参考是最后一项的参考。 您可以使用以下类似的方法分别设置每个项目的引用。
ref={(ref) => this.refs[data.id] = ref}
当然,此解决方案假定您在项目数据中具有唯一的ID或排序。
为了解释React Native文档,应谨慎使用直接操作(即refs)。 除非您出于我不知道的其他原因而需要它,否则在这种情况下不需要引用。 通常,跟踪FlatList中选定项目的最佳方法是将keyExtractor
和extraData
与处于状态的Javascript Map
对象结合使用。
React能够跟踪添加/删除/修改的项目的方式是为每个项目使用唯一的key
道具(最好是id,或者如果列表顺序不会改变,则必要时索引也可以工作)。 在FlatList中,如果您将使用keyExtractor
则将“自动”处理该keyExtractor
。 为了跟踪选定的项目,每当单击一个项目时,就可以从Map对象中添加/删除项目。 Map是一种对象类型,例如包含键值对的数组。 我们将使用此状态存储一个关键item.id
和一个布尔值true
用于选择的每个项目。
因此,我们最终得到这样的结果:
export default class Update extends Component { state = { data: [], selected: (new Map(): Map<string, boolean>) } renderItems = ({ item }) => { // note: the double ! operator is to make sure non boolean values are properly converted to boolean return ( <ExpandableItem item={item} selected={!!this.state.selected.get(item.id)} expandView={() => this.expandView(item)} /> ); } expandView (item) { LayoutAnimation.easeInEaseOut(); this.setState((state) => { const selected = new Map(state.selected); selected.set(item.id, !selected.get(item.id)); return {selected}; }); // the above allows for multiple expanded items at a time; the following will simultaneously close the last item when expanding a new one // this.setState((state) => { // const selected = new Map(); // selected.set(item.id, true); // return {selected}; // }); } render() { return ( <FlatList data={this.state.data} keyExtractor={(item, index) => `${item.id}`} renderItem={this.renderItems} /> ); } } const ExpandableItem = ({ item, selected, expandView }) => { return ( <TouchableNativeFeedback onPress={expandView}> <View style={styles.itemWrapperExpandable}> {/* ...insert other header code */} <View style={[styles.itemBody, selected && styles.itemBodySelected]}> <Text style={styles.itemBodyText}> some more information about this update will appear here </Text> </View> </View> </TouchableNativeFeedback> ); }
您必须使用styles.itemBodySelected
使其看起来像您想要的。 请注意,不需要renderItem
的单独功能组件<ExpandableItem />
,而是我更喜欢结构代码的方式。
有用的网址:
https://facebook.github.io/react-native/docs/flatlist.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.