经过一些研究,似乎我需要使用PureComponent而不是常规Component来提高FlatList的速度。这样,它将不会仅呈现已更改的行,而是仅重新呈现整个列表。但是,当我以这种方式进行操作时,统一列表不会重新呈现。
这个问题How to re-render flatlist?和其他类似的问题指出,我必须在我的extradata={this.state}
中使用FlatList
,以便可以查看数据源中是否发生了任何数据更改,但是它不起作用
我尝试过this.state,this.state.symbols,尝试使用布尔值并在onPress函数中强制更改它,但似乎没有任何效果。
我将列表项从render函数移到了外部js文件中的自己的类中
export default class MyListItem extends React.PureComponent {
render() {
const { item } = this.props;
return (
<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.coinName.toUpperCase()} {item.symbol}
</Text>
</View>
</View>
);
};
}
我的renderListItem函数现在看起来像这样
renderListItem = ({ item , index}) => {
return(
<TouchableOpacity
onPress={() => this.onPressListItem(index)}
>
<MyListItem
item={item}
/>
</TouchableOpacity>
)
}
这是onPress函数。如您所见,这里的状态已更改,所以不确定为什么
extraData
看不到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
});
}
这是我的平面清单
<FlatList
data={this.state.symbols}
extraData={this.state.symbols}
keyExtractor= {(item, index) => item.symbol}
ItemSeparatorComponent={this.renderListSeparator}
renderItem={this.renderListItem}
/>
最佳答案
您可能需要像这样在thePressedSymbol
函数中操纵onPressListItem
onPressListItem = ( index ) => {
const copyOfSymbolsList = [...this.state.symbols];
thePressedSymbol = {
...copyOfSymbolsList[index],
iconName: copyOfSymbolsList[index].iconName === 'md-star' ? 'md-star-outline' : 'md-star';
}
copyOfSymbolsList[index] = thePressedSymbol;
this.setState({
symbols: copyOfSymbolsList
});
}
这是因为在
Javascript
中,对象是reference
类型。您可以在控制台中尝试var person1={
name: 'John',
age: 10
}
var person2 = person1;
console.log(person1===person2); // output: true
person2.age = 20;
console.log(person1===person2); // output: true
console.log(person1.age, person2.age); // output: 20 20
var person3 = {...person1};
console.log(person1===person3}; // output: false
这意味着,为了重新渲染
FlatList
,您需要传递一个全新的symbol
项来替换数组中的现有项(这是我上面的解决方案所做的事情);或者(我还没有尝试过),您也可以实现自己的FlatList
组件进行深度比较,而不是深度比较。关于javascript - 即使使用extraData = {this.state},PureComponent FlatList也不会重新呈现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55448762/