Kireeti K
Kireeti K

Reputation: 1520

React Native require(image) returns number

I have a js file with one component EventCard, which takes event name, date, event image etc. If event image does not exist I want to load a placeholder image. Now that statement looks like this

constructor(props){
    super(props);
    let imgUrl = props.image ? props.image : require("../assets/images/image.jpg");
    this.state = {image: imgUrl}
}

I am using this.state inside render for source like

source={{uri: this.state.image}}

I strangely get 11 when doing a require for the placeholder image and the react native throws error saying 'value for uri cannot be cast from Double to String'.

Help is much appreciated.

Thanks

Upvotes: 24

Views: 20079

Answers (8)

Asher
Asher

Reputation: 403

If you went down the rabbit hole of discovering this because nothing is showing, remember to set the height and width of the image too in order for it to display. Once set, the require and import methods were working for me.

Upvotes: 0

MJ Studio
MJ Studio

Reputation: 4611

Internally, React Native static image require resolved as a number.

I can prove with the React Native typescript type declaration.

// your file
import { ImageSourcePropType } from 'react-native';

// @types/react-native
/**
 * @see https://facebook.github.io/react-native/docs/image.html#source
 */
export type ImageSourcePropType = ImageURISource | ImageURISource[] | ImageRequireSource;
...
export type ImageRequireSource = number;


The ImageRequireSource type is just a number type. And it can be a one of ImageSourcePropType.

Upvotes: 0

Uthaya
Uthaya

Reputation: 1

You can try this,

import React, {Component} from 'react';
import {StyleSheet,ImageBackground} from 'react-native';

import bgSrc from './images/bgfrm.png';

export default class Wallpaper extends Component {
  constructor(props){
    super(props);
    let imgUrl = props.image ? props.image :bgSrc;
    this.state = {image: imgUrl};
}

  render() {
    return (
      <ImageBackground style={styles.picture} source={this.state.image}>
        {this.props.children}
      </ImageBackground>
    );
  }
}

const styles = StyleSheet.create({
  picture: {
    flex: 1,
    width: null,
    height: null,
    resizeMode: 'cover',
  },
});

Upvotes: 0

Kireeti K
Kireeti K

Reputation: 1520

After some research and some help from @Fawaz and @Haider I understood require returns a number. This means we can use a number directly with source instead of require and it works

<Image source={11} />

This should display an image from your local resource if you have any image corresponding to that number. So when wanting to decide whether to show server sent url or a local resource like in my case. we can go with @Fawaz answer which basically inserts a {uri: "image-link"} or require("image") where require will be resolved to a number and when used with source you will put either the object or number which are the standard ways according to the documentation.

Upvotes: 11

Fawaz
Fawaz

Reputation: 3560

You need to assign image source directly when using require.

constructor(props){
  super(props);
  let imgUrl = props.image ? { uri: props.image } : require("../assets/images/image.jpg");
  this.state = { image: imgUrl };
}

and then in your render:

source={this.state.image}

Upvotes: 21

gazdagergo
gazdagergo

Reputation: 6691

Do not use the require dynamically. Detailed explanation in this post: React Native - Image Require Module using Dynamic Names

Upvotes: 0

Haider Ali
Haider Ali

Reputation: 1285

You can simply do this

constructor(props){
    super(props);
    let imgUrl = props.image ? props.image : null
    this.state = {image: imgUrl}
}

source={imgUrl == null ? require("../assets/images/image.jpg") : this.state.image}

Upvotes: 1

leitdeux
leitdeux

Reputation: 94

According to the documentation, the source prop of <Image /> only takes in a path to the resource (either local or remote). Here's how that might look in your example:

import React, { Component } from 'react';
import { Image } from 'react-native';


class EventCard extends Component {

  constructor(props) {
    super(props);

    const imgUrl = props.image || require('../assets/images/image.jpg');
    this.state = { image: imgUrl };
  }

  render() {
    return (
      <Image
        source={this.state.image}
      />
    );
  }
}

export default EventCard;

Upvotes: -1

Related Questions