Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Image & ListView] Image in ListView is not updated when re-rendering #1417

Closed
lazywei opened this issue May 27, 2015 · 32 comments
Closed

[Image & ListView] Image in ListView is not updated when re-rendering #1417

lazywei opened this issue May 27, 2015 · 32 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@lazywei
Copy link

lazywei commented May 27, 2015

Say I have such row in ListView

return (
        <View style={styles.chatRow}>
          <Image source={{ uri: otherUser.avatarUrl }} style={styles.chatAvatar} />
          <View style={styles.chatRowInfo}>
            <Text style={styles.chatRowName}> {otherUser.name} </Text>
            <Text style={styles.chatRowText}> {Tool.trimToLength(chatContent, 40)} </Text>
            <Text style={styles.chatRowText}> {otherUser.avatarUrl} </Text>
          </View>
        </View>
    );

When the state changes, the Text's are re-rendered but the Image isn't. The last Text shows that the avatarUrl is updated correctly. However, the Image still shows the old picture.
I'm wondering if this is due to Image doesn't compare {uri: xxx} deeply?

Thanks

@JohnyDays
Copy link
Contributor

It's not a comparison problem, because even the shallow comparison would return false, given you are creating different object instances on every render. So I'm afraid that's not the issue. I think in #1397 @ide mentioned there might be some bug in the Image class that causes Images not to change, might want to check that.

@brentvatne brentvatne changed the title Image in ListView is not updated when re-rendering [Image] Image in ListView is not updated when re-rendering May 29, 2015
@brentvatne brentvatne changed the title [Image] Image in ListView is not updated when re-rendering [Image & ListView] Image in ListView is not updated when re-rendering May 29, 2015
@adriansdev
Copy link

Have same issue, dataSource updated, row change is triggered and text updated but image does not rerender with new url

@adriansdev
Copy link

To answer my own problem - Image rerender works by adding a 'key' param with same value as the uri

#1397 (comment)

@ghost
Copy link

ghost commented Aug 5, 2015

Thank you for reporting this issue and appreciate your patience. We've notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.

@JohnyDays
Copy link
Contributor

@adrian-social-prod It does work, but it recreates the entire image view. This might not be problematic for 1 image, but for a few dozen it starts to become costly.

@adriansdev
Copy link

is still a problem in 0.8.0. list view image does not change when a new item is added to list unless the 'key' param is used to force the image to rerender. list is inside a TabBar item.

Seems like a major problem to me.

@brentvatne
Copy link
Collaborator

Hi there! This issue is being closed because it has been inactive for a while.

But don't worry, it will live on with ProductPains! Check out it's new home: https://productpains.com/post/react-native/image-listview-image-in-listview-is-not-updated-when-re-rendering

@KishPatel1996
Copy link
Contributor

Any chance I can reopen this?

@npomfret
Copy link
Contributor

Please re-open - I still have the issue with RN 0.28. It only seems to be a problem under certain circumstances. For me it happens when:

An image is added to the end of the list, AND it is adjacent in the list to another image. Adding key={uri} didn't help.

@merielleimpreso
Copy link

@npomfret: Were you able to fix the issue? I actually run into the same problem as yours. I'm using RN 0.30.

@ippy04
Copy link

ippy04 commented Jul 29, 2016

might try key={source.uri} instead of key={uri}

@carera
Copy link

carera commented Aug 15, 2016

Any updates on this? So far only hacking the key property seems to be solving the problem. In my case, i render multiple images in a for loop, and under certain condition, i render different images, so it has to look something like this:

const PATH_TO_IMG_1 = '/path/to/img/1.png'
const PATH_TO_IMG_2 = '/path/to/img/2.png'

render() {
  let arr = []
  for (let i=1; i < 100; i++) {
    if (cond) {
      arr.push(<Image source={require(PATH_TO_IMG_1)} key={PATH_TO_IMG_1+i}/>)
    } else {
      arr.push(<Image source={require(PATH_TO_IMG_2)} key={PATH_TO_IMG_2+i}/>)      
    }
  }
  return <View>{arr}</View>
}

Not sure if requiring image within a loop is efficient though.

@JohnyDays
Copy link
Contributor

You can just require the images at the top @carera
const IMG_1 = require('/path/to/img/1.png') but i don't think that's causing your problem ( it may be though )

@npomfret
Copy link
Contributor

@merielleimpreso i don't have a 'proper' fix, but hacking the key={uri} worked around it

@sscaff1
Copy link
Contributor

sscaff1 commented Sep 30, 2016

I'm having the same issue, but hacking the key={uri} also worked for me.

@npomfret
Copy link
Contributor

npomfret commented Nov 4, 2016

I don't think this should be closed. Images in ListViews don't re-render when you change the uri props. Feels like a proper bug.

@kelset
Copy link
Contributor

kelset commented Nov 22, 2016

I had a similar issue: every time I added a new element to the list, it did not populate the new "graphical row" with the correct data (even if in the state are correct) but with a copy of the first row.

Adding the key={id} worked for me.

@joeferraro
Copy link

joeferraro commented Feb 28, 2017

This is happening to me as well on 0.38. After updating the ListView, the Image in the new list element will only load after scrolling it off then on screen.

Update: this is not specific to ListView, it happens in any iterator, despite setting key.

@tianxind
Copy link

tianxind commented Mar 4, 2017

Yes seeing the same problem as well. This ticket shouldn't be closed.

@iamcco
Copy link

iamcco commented May 11, 2017

same issue

@hugomosh
Copy link

So it is open?
Does FlatList take care of this issue?

@mchandleraz
Copy link

mchandleraz commented Aug 2, 2017

I just ran into this.

I'm rendering an image using a remote URL, provided by my components initial state. Some UI actions can cause the URL that's store in component state to update. If I render the URL using a Text component, I see state updating. It does not update the Image component. I tried adding a key property of Math.random() and that causes the image to disappear entirely when state is updated.

EDIT: After taking a closer look at the URL being returned from my API, I noticed it's an http url. https url works fine!

@jose920405
Copy link

I join the question of @hugomosh

@eurobob
Copy link

eurobob commented Dec 4, 2017

@hugomosh @jose920405 I've also been experiencing this issue with FlatList :/

@TheToto
Copy link

TheToto commented Jan 30, 2018

I've this issue with FlatList too...

@brzonsea
Copy link

brzonsea commented Mar 6, 2018

I'm also experiencing this issue with Flatlist

@MERTKIRKALI
Copy link

+1

@lucidtheory
Copy link

lucidtheory commented Apr 1, 2018

RN 54.4 still happening

Same, when using the FlatList and adding a key = {uri} prop the image will update but then it just show up blank.

If I change the amount of rows in the FlatList or make a few further changes to the data in the FlatList then the new data will appear. I think this has something to do with the row in the FlatList not completely being redrawn maybe? Maybe iterators are caching image resources until the row is completely redrawn.

Something I am doing for now as a workaround is using the pull to refresh. I don't love it but it is the only thing that kind of works for the user experience right now.

     <FlatList
          ....
          refreshing = {false}
          onRefresh = {() => {
            let flatListData = this.state.data
            this.setState({data: []})
            this.setState({data: flatListData})
          }}
          ....more code
     />

basically emptying and refilling the data when a user pulls down to refresh the list.

@robisaks
Copy link

Someone on StackOverflow report that if you don't set the size on the image, it will re-render correctly. This fix didn't work for me but I'm posting it here for others just in case.

https://stackoverflow.com/questions/37529211/react-native-image-wont-rerender-when-state-changes

@alexandretournier
Copy link

Using react-native-image-cache instead of Image component solved this issue for me. Maybe related to kfiroo/react-native-cached-image#26

@h-asadollahi
Copy link

@alexandretournier may not be used.
I found the solution.
check this one

@alexandretournier
Copy link

thanks @Asadallahi

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests