【发布时间】:2019-03-31 11:27:31
【问题描述】:
直到 expo 允许我使用 Realm 数据库,我决定使用 Json 和 asyncstorage。无论如何,源数据都来自 Json,因此对于这个应用程序,将其保留为 json 是有意义的。
我有一个显示 json 的平面列表。列表中每个项目的左侧是一个星形图标。
当我触摸列表中的每个项目时,星号将变为实心表示它已被按下。再按一下,图标会变成星形轮廓,表示已取消选择。
onpress 函数看起来像这个符号是 JSON 数据的名称 JSON 数据有 3 个键...符号、名称和图标名称。符号是平面列表中被触摸的项目。
onPressListItem = ( symbol ) => {
for (var i = 0; i < this.state.symbols.length; i++){
if (this.state.symbols[i].symbol === symbol){
const copyOfSymbolsList = [...this.state.symbols];
if (copyOfSymbolsList[i].iconName === 'md-star') {
copyOfSymbolsList[i].iconName = 'md-star-outline';
} else {
copyOfSymbolsList[i].iconName = 'md-star';
}
this.setState({ symbols:copyOfSymbolsList });
}
}
}
正如您在上面看到的,它基本上只是滚动整个 json 数组以找到合适的行,然后复制列表,更改数据,然后再次设置状态。
在我的像素 2 上的图标更改之前,该应用程序不是超级快,可能延迟半秒,并且列表中只有 100 条记录。如果列表进入数千行,我有点担心它会非常糟糕。
有没有更好/更快/更简单/更具反应性的方法来解决这个问题?
编辑
这是调用 onPress 函数的 renderListItem 函数
renderListItem = ({ item }) => {
return (
<TouchableOpacity
onPress={() => this.onPressListItem(item.symbol)}
>
<View style={{flex: 1, flexDirection: 'row'}}>
<View style={{backgroundColor: 'powderblue'}}>
<Ionicons style={styles.listItemIcon} name={item.iconName} />
</View>
<View style={{backgroundColor: 'skyblue'}}>
<Text style={styles.listItem}>
{item.name.toUpperCase()} {item.symbol}
</Text>
</View>
</View>
</TouchableOpacity>
);
};
编辑 #2 这是 FlatList 代码。
<View style={styles.mainContainer}>
<FlatList
data={this.state.symbols}
keyExtractor= {(item, index) => item.symbol}
ItemSeparatorComponent={this.renderListSeparator}
renderItem={this.renderListItem}
/>
</View>
【问题讨论】:
-
你是怎么得到这个功能的?没有办法引用被按下的确切项目吗?
-
我已经通过调用 onpress 函数编辑了问题
-
返回 JSX 的函数是一个组件。您应该创建自己的列表项组件,该组件接受每个项目的成员作为道具。然后,在该组件中,根据 icon 属性有条件地渲染图标。现在,您不会在每次更改一项时都重新渲染整个列表。
标签: javascript node.js json react-native expo