react-native: Image Component will not update correctly when passing in new url
So I have this basic network image component. It will probably look similar to the one in the Image Component documents. The question is that when I switch the url, for the image, the image itself will not change to the new one, although it seems to be calling the render function again.
Device: iOS Using: Mac React-Native: 0.26.3
import React from 'react'
import {
View,
Image
} from 'react-native'
const NetworkImage = React.createClass({
getInitialState() {
return {
source: this.props.source
}
},
componentWillReceiveProps(newProps) {
if (newProps.source !== this.props.source) {
this.setState({
source: newProps.source
})
}
},
render() {
console.log('source: ', this.props)
return (
<Image
style={this.props.style}
source={this.state.source}
onLoad={() => {
console.log('loaded image!')
}}
onLoadStart={() => {
console.log('load starting')
}}/>)
}
})
module.exports = NetworkImage
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 22
- Comments: 61 (16 by maintainers)
I’ve experienced that same issue. Try adding a
key={this.state.source.uri}
property to the imageStill broken on RN 61, even after adding the key prop, cache=“reload”, and converting http to https.
I was going through react native node modules and in react-native->Libraries->Image->ImageSource.js, following is defined. `/**
Copyright © 2015-present, Facebook, Inc. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. An additional grant of patent rights can be found in the PATENTS file in the same directory. @providesmodule ImageSource @flow */ ‘use strict’; // This is to sync with ImageSourcePropTypes.js.
type ImageURISource = { uri?: string, bundle?: string, method?: string, headers?: Object, body?: string, cache?: ‘default’ | ‘reload’ | ‘force-cache’ | ‘only-if-cached’, width?: number, height?: number, scale?: number, };
export type ImageSource = ImageURISource | number | Array; `
Which makes me think that there is prop called ‘cache’, possible values to which are given above. I added to source prop like follows. <Image source={{uri : myImage, cache: ‘reload’}} />
According to its definition, it should always reload the image from the server and not the cache. But it is not working.
Tried all of the suggestions above with no success 😦
@wagnermaciel key props doesn’t work in my case 😕
Still have the same problem, adding key, cache didn’t help
For me it worked on I combined key with date ie. key=
${this.state.source.uri}${new Date()}
Yep. The image component has been broken since 2016.
Hey folks is this issue still open? and May I take it? Thanks
It is not restricted to changing the URI. Even if I change the image at the same URI, it still loads the previously placed image. I’ll soon enough put reproduction steps. If I use Google Postman to do a simple GET request to the URI, I get the updated image. But Image component still loads the old image.
Even I’m facing this issue and any of the above solutions did not help me in any way. The Text component is printing proper URI during each render but the image still shows up the same.
Please look at the image and its URI.
Note: The image is rendering properly when i just make any small change and expo refresh the page.
Worked for me
@tobiasr In that case, is there any possibility to fix it by adding? new Date() right after the image URL. Something like that
https://image/image.jpg?${new Date()}
@npomfret I learned about the bug the hard way 😅 . It quite a serious one that probably should be reopened.
I’m still having this issue on android devices with the
"react-native": "0.70.5",
does anyone know which version this was fixed?Happy Friday,
I might have a solution - but it ain’t pretty…
After being severely p***ed off by this problem the past few days and trying everything from cache: reload and different image libraries like fast-image to no avail I happened to make an important observation after my [what felt like] 1000th time of trying to overcome this tenacious little bug.
I noticed that if I quickly dismounted and re-mounted the component which contained the Image component that the original image would load - this didn’t stack up with my original hypothesis (shared by many on this thread) that unmounting and remounting was causing the image component to work as expected.
So, instead of setting my image’s URI to the prop which I passed into my component I set it to a state variable. I then setup a useEffect hook which would execute whenever the URI prop changed - but instead of immediately updating the state I used the setTimeout function and updated the state’s copy of the URI after a few seconds … and it worked as expected.
When all other solutions didn’t work for us … we tried changing http to https and it worked perfectly without needed to add key.
Make sure that you are reading from https when running on iOS.
@shohailahm It might sound super hacky but the T workaround is to superpose new images on top of the “old” ones. This doesn’t depend on expo. You can find a example here: https://github.com/wcandillon/react-native-expo-image-cache/blob/master/src/Image.js#L86
@Charpeni: I wrote a snack here: https://snack.expo.io/@wcandillon/progressive-image-loading if you use such component (where uri is in the state and we change the value of the RN Image source) on a large collection of images, sometimes it will not refresh the image (5% of the time). Using the workaround above with
key
solves the issue but to creates a flicker in the image.The way I was able to work around this issue to to superpose the new Image component on top of the old one instead.