I've tried all possible solutions, and ended up implementing my own -- very fast and simple. Find complete solution here https://dev.to/dmitryame/implementing-fast-image-for-react-native-expo-apps-1dn3
Here is the code which should be self explanatory:
import React, { useEffect, useState, useRef } from 'react'
import { Image } from 'react-native'
import * as FileSystem from 'expo-file-system'
import PropTypes from 'prop-types'
const CachedImage = props => {
const { source: { uri }, cacheKey } = props
const filesystemURI = `${FileSystem.cacheDirectory}${cacheKey}`
const [imgURI, setImgURI] = useState(filesystemURI)
const componentIsMounted = useRef(true)
useEffect(() => {
const loadImage = async ({ fileURI }) => {
try {
// Use the cached image if it exists
const metadata = await FileSystem.getInfoAsync(fileURI)
if (!metadata.exists) {
// download to cache
if (componentIsMounted.current) {
setImgURI(null)
await FileSystem.downloadAsync(
uri,
fileURI
)
}
if (componentIsMounted.current) {
setImgURI(fileURI)
}
}
} catch (err) {
console.log() // eslint-disable-line no-console
setImgURI(uri)
}
}
loadImage({ fileURI: filesystemURI })
return () => {
componentIsMounted.current = false
}
}, [])// eslint-disable-line react-hooks/exhaustive-deps
return (
<Image
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
source={{
uri: imgURI,
}}
/>
)
}
CachedImage.propTypes = {
source: PropTypes.object.isRequired,
cacheKey: PropTypes.string.isRequired,
}
export default CachedImage
And you invoke the component like this:
<CachedImage
source={{ uri: `${item.getThumbUrl}` }}
cacheKey={`${item.id}t`}
style={styles.thumbnail}
/>
react-native-fast-image
asreact-native-fast-image-expo
is an old fork that hasn’t been updated in over a year and doesn’t look like it actually supports unejected expo apps. If you haven’t ejected your app then you cannot use this dependency in your project. – Andrewexpo eject
– hong developer