Created
December 29, 2021 22:49
-
-
Save tomasswood/08502e5a29974e48b6772956632dd34e to your computer and use it in GitHub Desktop.
React Native / Expo Fast Cached Image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useEffect, useState } from 'react'; | |
import { Image, ImageProps, ImageURISource } from 'react-native'; | |
import * as FileSystem from 'expo-file-system'; | |
import * as Crypto from 'expo-crypto'; | |
const getImageFileSystemKey = async (remoteURI: string) => { | |
const fileHash = await Crypto.digestStringAsync(Crypto.CryptoDigestAlgorithm.SHA256, remoteURI); | |
return `${FileSystem.cacheDirectory}${fileHash}`; | |
}; | |
type CachedImageProps = Omit<ImageProps, 'source'> & { | |
source: ImageURISource; | |
}; | |
const CachedImage = (props: CachedImageProps) => { | |
const [imgSource, setImgSource] = useState<ImageURISource>({}); | |
useEffect(() => { | |
if (props.source?.uri && props.source.uri !== imgSource.uri) { | |
getImageFileSystemKey(props.source.uri).then(async (fileSystemURI: string) => { | |
if (!props.source?.uri || props.source.uri === imgSource.uri || fileSystemURI === imgSource.uri) { | |
return null; | |
} | |
const remoteURISource = props.source; | |
try { | |
// Check the cached image exists | |
const cachedFileData = await FileSystem.getInfoAsync(fileSystemURI); | |
if (cachedFileData.exists) { | |
setImgSource({ uri: fileSystemURI }); | |
return; | |
} | |
// Download the remote image to the file cache | |
const imageObject = await FileSystem.downloadAsync(remoteURISource.uri, fileSystemURI); | |
setImgSource(imageObject); | |
} catch (error) { | |
// Fallback to the remote image | |
setImgSource(remoteURISource); | |
} | |
}); | |
} | |
}, [imgSource, props.source?.uri]); | |
return <Image {...props} style={props.style} source={imgSource} />; | |
}; | |
export default CachedImage; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment