I am having the worst issue with disappearing images. The images will initially load, but after I navigate away from the component, they will disappear and not come back. All the images are in my app package and should be bundled with the app.
Using Expo 33 on a Fire Tablet. I have set my assetBundlePatterns
to "**/*"
and all the images are preloaded.
My root component:
import React from 'react'
import Navigator from '~/navigation'
import { AppLoading } from 'expo'
import Sentry from 'sentry-expo'
import { SENTRY_DSN } from 'react-native-dotenv'
import { loadAssetsAsync } from '~/utils/assets'
Sentry.config(SENTRY_DSN).install()
export default class AppRoot extends React.Component {
state = {
isReady: false,
}
_loadAssetsAsync() {
const imageAssets = [
// Slides
require('~/assets/slides/1.jpg'),
require('~/assets/slides/2.jpg'),
require('~/assets/slides/3.jpg'),
require('~/assets/slides/4.jpg'),
// Products
require('~/assets/products/category/1.jpg'),
require('~/assets/products/category/2.jpg'),
require('~/assets/products/category/3.jpg'),
require('~/assets/products/category/4.jpg'),
]
const fontAssets = {
'brush-script': require('~/assets/fonts/brush-script.ttf'),
}
return loadAssetsAsync(imageAssets, fontAssets);
}
render() {
if (!this.state.isReady) {
return (
<AppLoading
startAsync={this._loadAssetsAsync}
onFinish={() => this.setState({ isReady: true })}
onError={console.warn}
/>
)
}
return <Navigator />
}
}
assets.js
import { Image } from 'react-native'
import * as Font from 'expo-font';
import { Asset } from 'expo-asset';
export const cacheFonts = fonts => Font.loadAsync(fonts)
export const cacheImages = images => (
images.map(image => {
if (typeof image === 'string') {
return Image.prefetch(image)
} else {
return Asset.fromModule(image).downloadAsync()
}
})
)
export const loadAssetsAsync = (images, fonts) => {
const imageAssets = cacheImages(images)
const fontAssets = cacheFonts(fonts)
return Promise.all([imageAssets, fontAssets])
}
Component with image (ProductItem.js):
import React from 'react'
import { StyleSheet, TouchableOpacity, Image, Text } from 'react-native'
import { Actions } from 'react-native-router-flux'
export default class ProductItem extends React.Component {
render() {
const { product } = this.props
return (
<TouchableOpacity
style={styles.productItem}
onPress={() => Actions.product({ product })}
>
<Image
style={styles.productImage}
source={product.image}
/>
<Text style={styles.productTitle}>
{ product.name }
</Text>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
productItem: {
flex: 1,
margin: 20,
alignItems: 'center',
},
productImage: {
flex: 1,
width: 200,
height: 200,
resizeMode: "contain",
},
productTitle: {
color: '#ffffff',
fontSize: 20,
},
})
Grid containing image component (ProductGrid.js)
import React from 'react'
import Grid from 'react-native-grid-component'
import ProductItem from '~/components/ProductItem'
export default class ProductGrid extends React.Component {
renderProduct = (product, index) => (
<ProductItem product={product} />
)
render() {
const { products } = this.props
return (
<Grid
data={products}
numColumns={2}
renderItem={this.renderProduct}
keyExtractor={(item, index) => item.name}
/>
)
}
}
The products array:
[
{
name: '1',
type: 'type1',
blurb: 'Lorem ipsum...',
image: require('~/assets/products/category/1.jpg')
},
{
name: '2',
type: 'type2',
blurb: 'Lorem ipsum...',
image: require('~/assets/products/category/2.jpg')
},
{
name: '3',
type: 'type3',
blurb: 'Lorem ipsum...',
image: require('~/assets/products/category/3.jpg')
},
...
]