我正在使用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会被下一个覆盖 .
2 回答
为了解释React Native文档,应谨慎使用直接操作(即refs);除非你因为某些其他原因需要它,否则我在这种情况下是必要的 . 通常,跟踪FlatList中所选项目的最佳方法是将
keyExtractor
和extraData
道具与状态中的JavascriptMap
对象结合使用 .React能够跟踪正在添加/删除/修改的项目的方式是为每个项目使用唯一的
key
prop(最好是id,或者如果列表顺序不会更改,则必要的索引可用) . 在FlatList中,如果您将使用keyExtractor
prop,则会处理"automagically" . 为了跟踪所选项目,我们可以在点击其中时添加/删除Map对象中的项目 . Map是一种对象类型,类似于保存键值对的数组 . 我们将在状态中使用它来为所选的每个项存储键item.id
和布尔值true
.所以,我们最终得到这样的东西:
你必须使用
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
https://reactjs.org/docs/lists-and-keys.html#keys
你对自己的假设是正确的 . Ref用下一个项目覆盖,所以ref是最后一个项目的ref . 您可以使用类似下面的内容来单独设置每个项目 .
当然,此解决方案假设您的商品数据中包含唯一ID或排序 .