facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
118.35k stars 24.25k forks source link

Image never reloads with same uri #12606

Open RyanMitchellWilson opened 7 years ago

RyanMitchellWilson commented 7 years ago

I am using an Image component to display a profile picture but no matter what I do to the image component it will not reload the image. I have to use the same url for the profile pictures so I tried to give the Image a unique key prop to try and get it to reload the image but it still just uses the image from cache. I have changed the image on the server countless times but the Image component only shows the original image it got for the url.

It would be great if there was a prop to pass into Image that forces it to refresh the image every time it is rendered.

In a perfect world it would display the image from cache while fetching the new image, compare the two then decide if the image has changed.

chetna-webonise commented 4 years ago

Hi , adding some extra params in the image uri worked for me. Though it is not a proper solution for this issue.

const ImageUrl = ${gameBgImg}?time=${new Date()}; <Image source={{ uri: ImageUrl, cache: 'reload' }} key={new Date().getTime()} / >

Tyfoods commented 4 years ago

Experienced same issue. Used randomized parameter to solve it.

Something like: <Image source={{uri: 'exampleurl.com?'+Math.random()}}/>

Very bad solution, hoping for a fix on this for sure!

Yaolegol commented 4 years ago

still is problem

PriyaKailash commented 4 years ago

add a 'time=' param along with image URL, works as well.

<Image source={ { uri : this.props.userData.profileImgURL + '?time=' new Date() }} />

Hi, Thanks. This is working for me on Android, but it's taking time to load the image

ahkay commented 3 years ago

This is still problem for me - the dummy params workaround isn't acceptable, as my users have super low spec devices, are very data-limited and need to load hundreds of images each render but on the odd occasion that an image changes, it must update.

Saving a timestamp in the URI is also an unusable hack because the images are managed, updated and accessed by a main rails app using a gem. The gem stores and retrieves filenames with a specific syntax.

Is there no way to access the cache, even if it means diving into some native code? The ability to flush an image of a specific reference from the cache seems like a trivial function.

nguyentrannhan commented 3 years ago

+1

cyberdude commented 3 years ago

+1. Same issue here

WasimIbKhan commented 3 years ago

+1, still an issue, tried all the solutions that are practical for my app.

martinivanalfonso commented 3 years ago

Still an issue, my use-case is updating the image 2/·3 times in less than a second without flickering (sort of live streaming). Using time params, intervals and images on top of each other I found a way to partially overcome the issue.

However after updating the image 5/6 times in a row it simply stops updating until I unmount and remount, which can only indicate native cache issues as it's a very random behavior.

15110011 commented 3 years ago

source={{uri: <yourImgUrl> + '?' + new Date()}} key={<yourImgUrl>} onLoadStart={() => setIsShowLoading(true)} onLoadEnd={() => setIsShowLoading(false)} resizeMode="contain" After tried a lot of solutions above then this config is working for me.

ropmansk commented 3 years ago

Adding a timestamp or a random string to an url can result in poor performance because of downloading and rerendering image with each render cycle and flooding the cache.

A better workaround is to increment a counter on a backend every time the image gets updated and then append it to an url when loading image in the client.

amoerke commented 3 years ago

Hi

This worked for me on Android emulator:

<Image key={(new Date()).getTime()} source={{ uri: global.SERVER_ROOT + item['LOGO_IMG']+'?time'+(new Date()).getTime(), headers: {Pragma: 'no-cache' } }} style={{ width: width / 5, height: 100 }} />

Hope it hepls Malina

The magic that worked for me was key={(new Date()).getTime()}

Thanx Malina!

ydvnishant001 commented 2 years ago

I fixed this issue by adding random string. This is similar to adding date but it wasn't working for me because i may need to encode url for spacing.

<Image
    style={styles.image}
    source={uri: `${this.state.photoURL}&random=${Math.random().toString(36).substring(7)}`}
/>

OR If you don't have existing parameters in that image url.

<Image
    style={styles.image}
    source={uri: `${this.state.photoURL}?random=${Math.random().toString(36).substring(7)}`}
/>

this worked for me. Thank you.

MrGVSV commented 2 years ago

All the above solutions recommending appending a random string assume that the uri is a web URL. I don't think this will work for URIs that use the local file system (i.e. file:///Users/someuser/.../Documents/image.png). Appending a random query string results in the file not being found.

A prop like FlatList's extraData would be very useful for cases like this.

KrisLau commented 2 years ago

Experienced same issue. Used randomized parameter to solve it.

Something like: <Image source={{uri: 'exampleurl.com?'+Math.random()}}/>

Very bad solution, hoping for a fix on this for sure!

If you need it to only reload when the image changes you can just set it to just change the URL with the Math.random upon image update when you are saving the URL in the database instead of including the Math.random in the image source. So for example, in the update method for my image i just update it as

logoURL + `?invalidate-cache=${new Date().getTime()}`
RocketRonz commented 2 years ago

Messing around with the URL is not a great solution. If your image URLs are generated and contain validation information, eg. when using AWS Amplify, you can't just add an extra query parameter as a cachebuster.

I found that setting the "key" property to {new Date().getTime()} on the Image component achieves the same result.

koffhessel commented 2 years ago

The header image updates with either a change to the URI or the key of the element but it starts flickering on navigation to different pages. Anybody know a solution to this?

kravetsone commented 2 years ago

This bug has been around since 2017 and facebook still hasn't fixed it? Seriously?

localhostov commented 2 years ago

Thank you so much for not fixing this bug yet!!!!!

Turtleted21 commented 2 years ago

Hi, How do you add a query parameter on a require? I try to add one but It change the link to my source

my code:

<Viro3DObject // Chimere -------------------------------
      source={ChimereSources.chimereCaracteres[ChimereSourceBuild1].source}
     .....
    />
my json:
     epuisette_bleu_griffe: {
      source: require('../res/chimeres/epuisette_bleu_griffe/chimere.vrx'),
    },

I tried:

 source={
        ChimereSources.chimereCaracteres[ChimereSourceBuild2].source +
        '?' +
        new Date()
      }

and

epuisette_bleu_griffe: {
      source: require('../res/chimeres/epuisette_bleu_griffe/chimerevrx'+
      '?' +
      new Date()),
    },

Thanks

KrisLau commented 2 years ago

Messing around with the URL is not a great solution. If your image URLs are generated and contain validation information, eg. when using AWS Amplify, you can't just add an extra query parameter as a cachebuster.

I found that setting the "key" property to {new Date().getTime()} on the Image component achieves the same result.

This would stop the image from caching though which i still want to happen. That's why I'm only adding the extra parameter when the image is changed. The other solution would be to use react-native-fast-image and changing the default caching method as per the docs and this issue: https://github.com/DylanVann/react-native-fast-image/issues/721 which allows you to change the caching method but it also doesn't seem to be maintained anymore

haiderali3071 commented 1 year ago

I was using an array which was rendering some child components so quick fix is below

setPictures([]) setTimeout(()=>{ const data = fetch from server setPictures(data) },50)

vikrvm commented 1 year ago

Has anyone come up with another solution? The ones listed in this thread still don't work for me.

      <FastImage
        key={new Date().getTime()}
        source={{ uri: `${source}` }}
      />
KrisLau commented 1 year ago

@MyPalVikram what have you tried? this was mine from further up in the thread: https://github.com/facebook/react-native/issues/12606#issuecomment-1054393947

indyteo commented 1 year ago

Any solution for local images? The key trick does not work for me 😢

I have something like that:

<Image source={{ uri: "file://" + path }} {...props} />
k1mmm commented 1 year ago

Any solution for local images? The key trick does not work for me 😢

I have something like that:

<Image source={{ uri: "file://" + path }} {...props} />

For local images you can use url parameters

<Image source={{ uri: "file://" + path + '?v=' + <myCustomIncrementalStateValue> }} {...props} />

janusqa commented 1 year ago

If you are using expo npx expo i expo-image

import {Image} from "expo-image"
<Image source={{ uri: "blah.jpg" }} cachePolicy={"none"} />
samih-sghier commented 9 months ago

Bruh this is still an issue

VictorDev200 commented 8 months ago

Still an issue on Android. Using cache:'reload' doesn't apply any changes. Using '+ new Date()' on the src makes the image reload but takes like 30 seconds to trigger the change even reloading the component.

syafiq90 commented 8 months ago

// Generate a unique query parameter (timestamp) const uniqueQuery = ?timestamp=${new Date().getTime()};

const handleReloadImage = () => { // Set a new source with the updated URL setImageUrl(imageUrl + uniqueQuery); };

cliveportman commented 2 months ago

If you are using expo npx expo i expo-image

import {Image} from "expo-image"
<Image source={{ uri: "blah.jpg" }} cachePolicy={"none"} />

Something as basic as this shouldn't require installing an additional library.

mimo-10 commented 2 days ago

But isn't adding new images mean that the cashed data will grow, that could lead to decrease performance over time ?!