1

I have an avatar component and inside it it has the following XML

    <Image
      source={avatars && avatars[deferredKey]
        ? { uri: avatars[deferredKey] } : defaultAvatar}
      style={{
        width: size, height: size, borderRadius: size / 2, ...containerStyle,
      }}
      onError={this.onError}
    />

When the app loads avatars is null so defaultAvatar loads, then a few seconds later the image receives new props and it should switch to the the uri image but it fails to do that.

When I change the code to

   <Image
      source={{ uri: avatars[deferredKey] }}
      style={{
        width: size, height: size, borderRadius: size / 2, ...containerStyle,
      }}
      onError={this.onError}
    />

Then the component works as expected with originally the avatar loads blank and a few seconds later it loads the uri image correctly.

The issue seems to only exist when the avatar has to switch from a locally stored asset to a uri.

Adam Katz
  • 6,999
  • 11
  • 42
  • 74
  • Is there a state update after avatars is updated ? – Guruparan Giritharan May 20 '20 at 16:30
  • no im logging avatars[deferredKey] and it runs exactly twice, once as null and once as the correct route. Notably with either version of the code if i refresh the component it works correctly, the issue is only on first load – Adam Katz May 20 '20 at 16:37

2 Answers2

0

like usual i fought with this for 2 days and then figured out the answer straight after posting.

I edited the code to just use the prop defaultSource and it works as expected now

    <Image
      source={{ uri: avatars[deferredKey] }}
      style={{
        width: size, height: size, borderRadius: size / 2, ...containerStyle,
      }}
      defaultSource={defaultAvatar}
    />
Adam Katz
  • 6,999
  • 11
  • 42
  • 74
  • this actually isnt the right solution as it puts an image while the avatar is loading as well as when its unsuccessful which is not what i want so im not going to mark it correct if someone can find a way for the toggle one to work it would be much better – Adam Katz May 22 '20 at 11:04
0

I found the answer here, https://github.com/facebook/react-native/issues/9195. It seems that it is essentially a react-native Image bug and has been for some time.

According to the spec you should be able to do something like this

<Image source={{uri : myImage, cache: 'reload'}} />

But even that doesn't work.

Turns out the best solution that's been working since 2016 is to essentially add a key to your Image component that points to the source value from state:

key={this.state.source.uri}
JackDev
  • 4,891
  • 1
  • 39
  • 48