直到博览会让我使用Realm数据库ive决定与Json和asyncstorage一起使用。源数据仍然来自Json,因此对于此应用程序,将其保留为json是有意义的。
我有一个带有json的单位列表。列表中每个项目的左侧是一个星形图标。
当我触摸列表中的每个项目时,星标将变实,表明已被按下。再按一次,该图标将是星星的轮廓,表明它已被取消选择。
onpress
函数看起来像这个符号是JSON数据的名称,JSON数据具有3个键... symbol,name和iconName。符号是要触摸的平板列表中的项目。
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条记录。我有点担心列表是否进入数千行,这真的很糟糕。
是否有更好/更快/更简单/更多反应方式来解决此问题?
编辑
这是renderListItem函数,它调用onPress函数
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>
答案 0 :(得分:0)
我来宾,您的json结构是这样的。
the_data = [
{'iconName': 'xxx', 'symbol': '<i class="fa fa-items"></i>'}
]
您可以通过索引访问此结构,并将索引传递给onPressListItem函数。
renderListItem = ({ item }, index) => {
return (
<TouchableOpacity
onPress={() => this.onPressListItem(index)}
>
<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>
);
};
通过这种设计,您不必迭代json。
onPressListItem = ( index ) => {
the_dataobj = the_data[index];
the_dataobj.iconName = 'md-start';
if (the_dataobj.iconName === 'md-start'){
the_dataobj.iconName = 'md-start_outline';
}
//you don't need a extra else here, is in-necesarry
the_data[index] = the_dataobj;
//set state ... do more
}
顺便说一句:这与反应无关,您的工作流程的正确设计应独立于框架库。
祝您生日快乐!
答案 1 :(得分:0)
对于您阅读的那些人,接受的答案未正确更新屏幕上的呈现列表。所以下面是我的实际工作代码。我很确定是因为接受的答案没有使用this.setState函数将值写回到数组。
如果if else则需要在其中包含else,因为当用户两次敲击同一行时,我希望它撤消其更改。
所有这些,更新仍然非常缓慢。与在问题中使用for循环时的速度大致相同。不知道为什么。
onPressListItem = ( index ) => {
const copyOfSymbolsList = [...this.state.symbols];
thePressedSymbol = copyOfSymbolsList[index];
if (thePressedSymbol.iconName === 'md-star') {
thePressedSymbol.iconName = 'md-star-outline';
}else{
thePressedSymbol.iconName = 'md-star';
}
copyOfSymbolsList[index] = thePressedSymbol;
this.setState({ symbols:copyOfSymbolsList });
}