react-native-expo-image-cache
react-native-expo-image-cache copied to clipboard
Add cache support to components without replacing the Image element
Hi,
I'm new to Github so I really don't know yet how to open a branch or pull a request, so I'm posting this idea/contribution here.
Well, as many, I use 3rd party components for my app, and many of those are built around the image component. So in order to make them work with this react-native-expo-image-cache I either have two options:
Option 1: I fork all the 3rd party components I use and replace the image object with this image object.
Option 2: I create a function to make the CacheManager support those components without forking them.
So, being the second option more apealing, I came up with this little function, which should allow me to use the CacheManager within 3rd party components:
// Returns the cached uri for an image, otherwise the fallback uri and triggers cache operation
// stateUri : set as Control state var where to store the cached uri for the image.
// uri : the original URI to be/already cached
// fallbackUri : the URI to return while not yet cached
// listener : listener that receives the cached URI when obtained and sets stateUri
function uriCache(stateUri: string, uri: string, fallbackUri: string, listener: Listener): string {
if ((typeof stateUri === 'string') && stateUri)
return stateUri
else {
CacheManager.cache(uri, listener)
}
return fallbackUri
}
Usage..... Let's say I'll use the avatar component from the reac-native-elements library, and wish to cache the picture:
const profileUri = 'https://somewhereInTheWeb/somePic.jpg'
const defaultUri = 'https://somewhereInTheWeb/default.jpg'
class MyView extends React.Component {
state = {
cachedUri = undefined
}
render = () => (
<Avatar source = {{
uri: uriCache( state.cachedUri, profileUri, defaultUri,
uri => this.setState({cachedUri: uri}) )
}}
/>
}
}
And the same way with any component receiving an URI as parameter.....
Another application could be when you need to wait for the Cached URI straightforward, then, this function could solve that situation:
const getCachedUri = (uri: string): Promise<string> => new Promise (resolve => {
const listener = (uri: string) => resolve (uri)
CacheManager.cache(uri, listener)
})
usage:
const someImageUri = 'https://somewhereInTheWeb/somePic.jpg'
let cachedUri = await getCachedUri(someImageUri)
or, in case I have an array of images:
const someUriArray = ['https://somewhereInTheWeb/somePic.jpg',
'https://somewhereInTheWeb/anotherPic.jpg',
'https://somewhereInTheWeb/yetAnotherPic.jpg']
let newCachedArray = someUriArray.map(uri => await getCachedUri(uri))
But i'm just not sure about this last form might solve the problem for image arrays properly.
@Piropa Is it possible that what you are looking for is to pass a custom component that will replace the default which is <Image> from React Native. For example:
import {Image} from "react-native-expo-image-cache";
const preview = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
const uri = "https://firebasestorage.googleapis.com/v0/b/react-native-e.appspot.com/o/b47b03a1e22e3f1fd884b5252de1e64a06a14126.png?alt=media&token=d636c423-3d94-440f-90c1-57c4de921641";
<Image style={{ height: 100, width: 100 }} {...{preview, uri}} component={Avatar} />
If this is what you are looking for, we can introduce it.
Thank you wCandillon,
It's an interesting proposal, haven't thought it that way. It will work for simple-uri image components that use source as it's data source and that source is a simple uri.
Good,