在我的 Redux 商店中,我保留了一个活动的 Report 对象。这个复杂的对象有一个照片对象数组,由一个带有 id 字段和 uri 字段的对象组成。例如,报表对象可能如下所示:
{
title: "some title",
date: "some date",
... a bunch of other data
photos: [
{uri: someURI, id: some id},
{uri: someURI, id: some id},
{uri: someURI, id: some id},
]
}
我将这些图像 uri(它们不是本地文件,它们指向 firestore 存储)加载到 FlatList 中,如下所示:
<FlatList
ref={listRef}
numColumns={3}
columnWrapperStyle={{ marginBottom: 10 }}
nestedScrollEnabled={true}
showsVerticalScrollIndicator={false}
data={activeReport?.photos}
renderItem={renderImages}
/>
然后我用这个函数调用 renderItems:
const renderImages = ({ item, index }) => {
const screenWidth = ((Dimensions.get('window').width - 50) / 3)
const marginH = (index + 2) % 3 === 0 ? 10 : 0
return (
<AsyncImage
image={item}
key={item.id}
onPress={() => navigation.navigate('Photo', { image: item })}
containerStyles={{ width: screenWidth, alignItems: 'center'}}
onLongPress={() => {
Alert.alert('Delete Photo?', 'Are you sure you want to delete this photo?', [
{
text: 'Cancel',
style: 'cancel',
},
{
text: 'Delete',
onPress: () => {
_deleteImageAsync(item)
},
style: 'destructive',
},
])
}}
/>
)
}
最后,这是我的 AsyncImage 组件代码:
function AsyncImage({ imageStyles = {}, image, onPress, onLongPress, containerStyles }) {
const [loading, setLoading] = useState(true)
return (
<TouchableOpacity
key={image.id}
activeOpacity={0.7}
onPress={onPress}
onLongPress={onLongPress}
style={[styles.touchableWrapper, containerStyles]}>
<ImageBackground
source={require('../../../../assets/image.png')}
resizeMode='cover'
style={[styles.image, styles.placeholderImage]}
/>
<Image
style={[styles.image, imageStyles]}
source={{ uri: image.uri }}
resizeMode='cover'
onLoadEnd={() => {
setLoading(false)
}}
/>
{loading && (
<>
<ActivityIndicator animating={true} size={36} color={colors.colorPrimary} style={styles.indicator} />
</>
)}
</TouchableOpacity>
)
}
const areEqual = (prevProps, nextProps) => {
const { image } = nextProps
const { image: prevImage } = prevProps
return image.uri === prevImage.uri
}
const styles = StyleSheet.create({
touchableWrapper: {
borderRadius: 5,
overflow: 'hidden',
marginHorizontal: 5,
},
image: {
backgroundColor: colors.colorCharcoalDark,
resizeMode: 'cover',
width: '100%',
aspectRatio: 1,
borderColor: colors.colorGrayDark,
borderWidth: 0.5,
borderRadius: 5,
},
placeholderImage: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
indicator: {
position: 'absolute',
top: 0,
bottom: 0,
left: 0,
right: 0,
},
})
export default React.memo(AsyncImage, areEqual)
这是我的删除照片功能:
const _deleteImageAsync = async (photo) => {
if (!photo) return
try {
// delete image from report in firestore
const reportRef = db.collection('reports').doc(activeReport.reportID)
const report = (await reportRef.get()).data()
// make sure photo exists before trying to remove it from firestore
if (report.photos.some((p) => p.id === photo.id)) {
reportRef.update({
photos: firebase.firestore.FieldValue.arrayRemove(photo),
})
} else {
throw new Error('Could not delete photo. Please try again')
}
// delete photo from storage
const ref = storage.ref(activeReport?.reportID).child(photo.id)
await ref.delete()
dispatch(removeReportPhoto(photo))
} catch (error) {
// todo: handle error here
console.log('Delete photo: ', error.message)
alert('was not able to delete photo from cloud storage.')
}
}
问题
当我向数组中添加一张新照片时,一切都很好。但是,当我从数组中删除一个元素时,尽管我使用了 React.memo,但一些(但不是全部)图像会重新加载。
我花了数小时和数天试图找出原因。我迷路了。我希望在这个问题上得到一些帮助
如果有人需要查看我的更多代码,请告诉我,但这对我来说看起来很简单