1import { Image } from 'expo-image'; 2import { useCallback, useState } from 'react'; 3import { ScrollView, StyleSheet, Text, View } from 'react-native'; 4 5import Button from '../../components/Button'; 6import MonoText from '../../components/MonoText'; 7import { Colors } from '../../constants'; 8 9export default function ImagePlaceholderScreen() { 10 const [uri, setUri] = useState<string>(getRandomImageUri()); 11 const [isLoading, setIsLoading] = useState<boolean>(true); 12 13 const loadRandomImage = useCallback(() => { 14 setIsLoading(true); 15 setUri(getRandomImageUri()); 16 }, [uri]); 17 18 const source = { 19 uri, 20 cacheKey: 'CUSTOM_CONSTANT_CACHE_KEY', 21 }; 22 23 return ( 24 <View style={styles.container}> 25 <Image 26 style={styles.image} 27 source={source} 28 cachePolicy="disk" 29 onLoad={({ cacheType }) => { 30 if (cacheType === 'disk') { 31 alert('Image was loaded from the disk cache'); 32 } 33 setIsLoading(false); 34 }} 35 /> 36 37 <MonoText>{`const source = ${JSON.stringify(source, null, 2)}`}</MonoText> 38 39 <ScrollView style={styles.scrollView} contentContainerStyle={styles.actionsContainer}> 40 <Text style={styles.text}> 41 At first let's make sure the disk cache is cleared{'\n'} 42 43 </Text> 44 45 <Button 46 style={styles.actionButton} 47 title="Clear disk cache" 48 onPress={Image.clearDiskCache} 49 /> 50 51 <Text style={styles.text}> 52 Now load a new random source that{'\n'} 53 uses the constant as a cache key.{'\n'} 54 Do it multiple times and notice the image{'\n'} 55 is not changing when the source changes{'\n'} 56 57 </Text> 58 59 <Button 60 disabled={isLoading} 61 style={styles.actionButton} 62 title="Set random source uri" 63 onPress={loadRandomImage} 64 /> 65 </ScrollView> 66 </View> 67 ); 68} 69 70function getRandomImageUri(): string { 71 const seed = 100 + Math.round(Math.random() * 100); 72 return `https://picsum.photos/seed/${seed}/1200/800`; 73} 74 75const styles = StyleSheet.create({ 76 container: { 77 flex: 1, 78 padding: 20, 79 }, 80 image: { 81 height: 200, 82 borderWidth: 1, 83 borderColor: Colors.border, 84 }, 85 scrollView: { 86 marginTop: 10, 87 borderTopWidth: 1, 88 borderTopColor: Colors.border, 89 }, 90 actionsContainer: { 91 alignItems: 'center', 92 padding: 10, 93 }, 94 actionButton: { 95 marginVertical: 15, 96 }, 97 text: { 98 marginTop: 15, 99 color: Colors.secondaryText, 100 textAlign: 'center', 101 }, 102}); 103