Use Placeholder Image if the item.image is null (React Native)

Viewed 9038

I'm using FlatList to render multiple Images on the Screen. I want to render placeholder Image when item.img is null (items are fetched from react-redux).

Problems:

  1. I want to use placeholder image using 'require'. And it's using single curly brace. <Image source={ require('../assets/images/robot-prod.png') } style={styles.palceholderImage}/>. While normal Image rendering use two curly braces {{uri: item.img}}.

  2. Should I inline if(item.img) operator?

Here is _renderItem function.

 _renderItem = ({item}) => {
    let imgUrl = item.img;

    return (
      <TouchableWithoutFeedback
        onPress={() => this._handleCategoryPress(item.id)}>
        <Image
          key={item.id}
          source={{uri: item.img}}
          style={styles.rowImage}
          resizeMode="cover"
        />
      </TouchableWithoutFeedback>
    );
  }

This is API response

[
    {
        "id": 1,
        "name": "Gym",
        "image": "www.aws.blahblahblah"
    },
    {
        "id": 2,
        "name": "School",
        "image": null
    },
    {
        "id": 3,
        "name": "hollymo",
        "image": "www.aws.blahblahblah"
    },

Thanks

5 Answers

Try this

       item.image &&      
        <Image
          key={item.id}
          source={{uri: item.img}}
          style={styles.rowImage}
          resizeMode="cover"
        />

       !item.image &&      
        <Image
          key={item.id}
          source={require('../assets/images/robot-prod.png')}
          style={styles.palceholderImage}
          resizeMode="cover"
        />

You're looking for a full React component. An easy way of controlling rendering based on a completed API call is to use it as a promise and .then using this.setState If you're well versed in promises:

apiPromise = () => new Promise((resolve, reject)=> {
  apiData = myApiCall()
  resolve(apiData)
}

class StuffToRender extends Component {
constructor(props) {
  super(props)
  this.state = {
    loaded: false
  }
}
componentWillMount() {
  apiPromise().then (() => {
    this.setState({loaded: true})
  })
}

render() {
  return (
    <div>
      {this.state.loaded ? myContent : myContentWhileLoading}
    </div>
  )
}
}

Also, as a side note, the error you received from the other user's solution has nothing to do with the API/loading logic. It's the fact that you tried to return more than 1 html or component element:

render() {
  return (
    <div>
      stuff
    </div>
    <div>
      stuff2
    </div>
  ) //two sets of div elements expose
}

Here you are render 2 sets of items. This is what 'multiple children' means. But it's an easy fix. Just wrap the items in one single, larger container.

render() {
  return (
    <div>
      <div>
        stuff
      </div>
      <div>
        stuff2
      </div>
    </div>
  ) //everything wrapped into one single div
}

We can handle it better in react native by following approach.

As, base64 images render in react native out of the box.

So for your case,

  1. Get the base64 data for your placeholder image.

  2. In your component,

    const placeholderBase64image = "data:image/png;base64 [yourbase64imagedata]"

  3. Inside View, use it as:

    <Image source={{ uri: yourImageUri ? yourImageUri : placeholderBase64image }}/>

This works for me:

<Image source={ item.img ? { uri: item.img } : require('../images/dummy.png')} />

add place holder image in react native Image. use defaultSource tag

<Image source={{ uri: require('../images/dummy.png')}} 
            style={styles.itemImage}
            defaultSource={images.dummy} />
Related