Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native Image Invalid prop 'source' supplied to Image

I think this is a very annoying bug and feels like there is no solution but I want to share and ask.. I fetch data from server and I get image source from there and I use same Image paths in my mobile react-native App.

I fetch data from server like this :

$id = $request->userid;
$items = DB::table('item_user')->where('user_id', $id)->latest()->get();

$new = new Collection();

foreach($items as $item){

$new[] = array(
   ... ,
   'picturePath' => 'require'."('./". $item->picturePath ."')"
);

}

return $new;

and in front-end I try to render and I have these images locally. So when I use it locally like :

require('./images/...')

It works.. but like this its not working :

_renderItem = ({item}) => {

        return(
            <View>
               <Image source={ item.picturePath } style={{width: 15, height: 15}}/>
            </View>
        );

    };


    render(){
        return(

        <View>
           <FlatList
                data={this.state.items}
                renderItem={this._renderItem}
                keyExtractor={this._keyExtractor}
            />
         </View>
        );
    }

and I get error, How I can solve this :

Warning: Failed prop type: Invalid prop 'source' supplied to 'Image'.

like image 717
Berke Avatar asked May 14 '18 15:05

Berke


Video Answer


2 Answers

This is not the recommended way to assign dynamically images since React Native must know all your images sources before compiling your bundle.

According to the docs, here's an example of how to load images dynamically:

// GOOD
<Image source={require('./my-icon.png')} />;

// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />;

// GOOD
var icon = this.props.active
  ? require('./my-icon-active.png')
  : require('./my-icon-inactive.png');
<Image source={icon} />;

https://facebook.github.io/react-native/docs/images.html

Hope it helps

Edit: If you know all the images that could be loaded, you can try something like this:

// Create a file containing the references for your images

// images.js
const images = {
  logo: {
    uri: require('your-image-path/logo.png')
  },
  banner: { 
    uri: require('your-image-path/banner.png')
  }
}

export { images }; 


//YourComponent.js
import { images } from 'yourImagesPath';

// for this test, expected to return [ { name: logo }, { name: banner} ]
const imagesFromTheServer = (your fetch);

imagesFromTheServer.map(image => {
  if (!images[image]) {
    return <Text>Image not found</Text>;
  }
  return <Image source={images[image].uri} />; // if image = logo, it will return images[logo] containing the require path as `uri` key
});

This is quite hacky but may work.

Let me know if it helped

like image 75
soutot Avatar answered Oct 19 '22 03:10

soutot


As the React Native Documentation says, all your images sources needs to be loaded before compiling your bundle.

Adding a simple image in React Native should be like this:

<Image source={require('./path_to_your_image.png')} />

Let's say you have this:

const slides = {
  car: './car.png',
  phone: '../phone.png',
}

Then you pass slides as a parameter but still, you won't be able to use it like this (even though logically should work):

<Image source={require(props.car)} />

Use require() inside the sildes{}

const slides = {
  car: require('./car.png'),
  phone: require('../phone.png'),
}

And the use it like this:

<Image source={props.car} />
like image 45
abranhe Avatar answered Oct 19 '22 03:10

abranhe