0
votes

I was trying to install https://github.com/DylanVann/react-native-fast-image

what i did npm install --save react-native-fast-image-expo cuz I'm using expo

after that, I linked it using npm link react-native-fast-image-expo

when I build the project I get Unable to resolve "react-native-fast-image" from "App.js"

I tried linking the build but nothing

is it necessary ? to use it if i am getting images from an API?

2
Expo doesn’t allow linking native modules unless you have ejected the app. If you have ejected then you should be using react-native-fast-image as react-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.Andrew
what is ejection ? and what it does sorry im newmohamed adel
You should read through the answers to this question stackoverflow.com/questions/39170622/… you should read the documentation for both react-native and expo so that you are familiar with what each can and cannot do.Andrew
ejection is run expo ejecthong developer
thanks is there is any alternative to fast-images in expo ? in terms of perfromance ?mohamed adel

2 Answers

1
votes

It's not perfect, but you can use react-native-expo-image-cache as an alternative.

Example.js

import {Image} from "react-native-expo-image-cache";

// preview can be a local image or a data uri
const preview = { uri: "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}} />

Get the local image from a remote URI

import {CacheManager} from "react-native-expo-image-cache";

const {uri} = this.props;
const path = await CacheManager.get(uri).getPath();
// if path is undefined, the image download has failed 
-1
votes

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}
        />