Implementing Expo Image with React Native and Expo for Accelerating Image Loading and Caching

Tiempo de lectura: 2 minutos

expo-image is a modern Expo component optimized for loading images in a fast, efficient and cache integrated way. It’s designed to replace both the native React Native Image and external libraries such as react-native-fast-image.

Includes:

If your project already uses Expo SDK 49 or higher, you can install it directly with:

npx expo install expo-image 

This takes care of installing the compatible version for you automatically.

You can then import it like this:

import { Image } from 'expo-image'; 

4. Basic Usage

Example of how to render an image from a URL:

<Image source={{ uri: 'https://example.com/imagen.jpg' }} style={{ width: 200, height: 200, borderRadius: 10 }} contentFit="cover" /> 

5. Complete Example: ExpoImageCustom

A reusable component inspired by your FastImageCustom, but using expo-image:

<

pre class=”EnlighterJSRAW” data-enlighter-language=”generic” data-enlighter-theme=”” data-enlighter-highlight=”” data-enlighter-linenumbers=”” data-enlighter-lineoffset=”” data-enlighter-title=”” data-enlighter-group=””>import React, { useState } from ‘react’; import { View, ActivityIndicator, StyleSheet } from ‘react-native’; import { Image } from ‘expo-image’; import { marron } from ‘@/constants/Colors’; interface ExpoImageCustomProps { uri: string; style?: object; contentFit?: ‘contain’ | ‘cover’ | ‘fill’ | ‘scale-down’; cachePolicy?: ‘none’ | ‘disk’ | ‘memory’; onError?: () => void; onLoadEnd?: () => void; onLoadStart?: () => void; permitShowLoader?: boolean; loadingIndicatorColor?: string; indicatorSize?: ‘small’ | ‘large’; } const ExpoImageCustom: React.FC<ExpoImageCustomProps> = ({ uri, style, contentFit = ‘cover’, cachePolicy = ‘disk’, onError, onLoadEnd, onLoadStart, loadingIndicatorColor = marron, indicatorSize = ‘small’, permitShowLoader = true, }) => { const [loading, setLoading] = useState(true); const handleLoadStart = () => { setLoading(true); onLoadStart && onLoadStart(); }; const handleLoadEnd = () => { setLoading(false); onLoadEnd && onLoadEnd(); }; const handleError = () => { onError && onError(); setLoading(false); }; return ( <View style={[styles.container, style]}> {permitShowLoader && loading && ( <ActivityIndicator size={indicatorSize} color={loadingIndicatorColor} style={styles.loadingIndicator} /> )} <Image source={{ uri }} style={[styles.image, style]} contentFit={contentFit} cachePolicy={cachePolicy} onLoadStart={handleLoadStart} onLoadEnd={handleLoadEnd} onError={handleError} /> </View> ); }; const styles = StyleSheet.create({ container: { position: ‘relative’, }, image: { width: ‘100%’, height: ‘100%’, }, loadingIndicator: { position: ‘absolute’, top: ‘50%’, left: ‘50%’, transform: [{ translateX: -15 }, { translateY: -15 }], }, }); export default ExpoImageCustom;

import React from 'react'; import { View, StyleSheet } from 'react-native'; import ExpoImageCustom from '@/components/ExpoImageCustom'; export default function EjemploScreen() { return (    ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, image: { width: 300, height: 200, borderRadius: 10, }, }); 

Leave a Comment