[英]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.