Luis Rizo
Luis Rizo

Reputation: 2109

Error passing required() Image as a prop

I have a file called data.js where I export an object, which one of its elements is an Image. This is how it looks:

var data = [
  {
    "id": 1,
    "Category": "Category Title",
    "Image": require("../images/comingsoon.png"),
    "Summary": ""
  },

And then in another component I import the data variable and I pass the data.Image to another component as a prop using FlatList.

<FlatList
   style={{margin:5}}
   numColumns={2}
   data={this.state.data}
   renderItem={({item}) => item}
/>

item looks like this:

<CategoryItem key={item.id} Image={item.Image} Category={item.Category}/>

And then I use the Image prop inside CategoryItem like so:

<Image source={this.props.item.Image} style={styles.CategoryImage}>

And this works perfectly!... But I wanted to simply pass Item as a prop to CategoryItem like so:

<CategoryItem key={item.id} item={item}/>

And once inside CategoryItem, I would do:

  render(){
    const {Category, Image} = this.props.item;

And call the Image simply by doing

<Image source={Image} style={styles.CategoryImage}>

However, when I do that, the app crashes and it says that Image is a number. Screenshot of crash report

After logging what item looks like, I found out that require()ing turns the image into a numberConsole results of console.log(Image), and it should work by simply passing it differently, it crashes. Any thoughts?

Upvotes: 0

Views: 1346

Answers (1)

jevakallio
jevakallio

Reputation: 35920

The issue is that the local variable Image is shadowing the component named Image.

Your code, simplified, might look something like this:

import { Image } from 'react-native';

class CategoryItem extends React.Component {
  render() {
    const { Category, Image } = this.props;
    return <Image source={Image} />
  }
}

Instead of the <Image /> declaration referring to the component as you'd expect, it refers to the Image prop.

This is easy to fix by renaming the variable:

class CategoryItem extends React.Component {
  render() {
    const { Category, Image: imageSource } = this.props;
    return <Image source={imageSource} />
  }
}

The reason the error tells you the component is a number is a implementation detail of how the React Native asset imports work. When you import an image with require('path.jpg'), React Native assigns that image a unique numeric ID and returns that instead of a image path descriptor. This is beneficial for performance reasons, so instead of passing a descriptor over the native-javascript bridge for each render, it can pass over a number, which are cheaper to serialize and to marshall.

As a side note, it's a common React practice to declare your component props in lowerCamelCase, so instead of <CategoryItem Image={} /> you would have <CategoryItem image={} />. This is just a convention, but in this case it would have avoided this error.

Upvotes: 2

Related Questions