0

在我的 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,但一些(但不是全部)图像会重新加载。

我花了数小时和数天试图找出原因。我迷路了。我希望在这个问题上得到一些帮助

如果有人需要查看我的更多代码,请告诉我,但这对我来说看起来很简单

4

0 回答 0