0

Not sure why this works:

import React from 'react';
import './imageDisplay.css';

// /src/content/GandJBoat.jpg'


const ImageDisplay = (props) => 
    (
    <div className='imageContainer'>
        {/* <img src={require(`${props.imageSource}`)} alt="" /> */}
        <img src={require('../../content/GandJBoat.jpg')} alt=''/>
    </div>
);

export default ImageDisplay;

and this doesn't:

import React from 'react';
import './imageDisplay.css';

// /src/content/GandJBoat.jpg'


const ImageDisplay = (props) => 
    (
    <div className='imageContainer'>
        <img src={require(`${props.imageSource}`)} alt="" />
        {/* <img src={require('../../content/GandJBoat.jpg')} alt=''/> */}
    </div>
);

export default ImageDisplay;

when I run the second one I get the error

Error Log

I have no idea why the two would be different? I've tried quite a few different ways now and I'm not sure why it would behave like this. I want to randomly display images, the top level function passes a random image url to the component.

James
  • 326
  • 3
  • 13

2 Answers2

0

Require is a CommonJs function, and its path system doesn't work as URL endpoints. As I can see, you are using url-loader.

Follow this example:

import React from 'react';
import path from 'path';
import './imageDisplay.css';

// /src/content/GandJBoat.jpg'


const ImageDisplay = (props) => 
    (
    <div className='imageContainer'>
        <img src={require(`${path.join(__dirname, props.imageSource)}`)} alt="" />
        {/* <img src={require('../../content/GandJBoat.jpg')} alt=''/> */}
    </div>
);

export default ImageDisplay;

I strongly recommend use EcmaScript Modules instead of CommonJs modules.

0

The images need to be able to statically analyzed so that the packager could resolve them and package them in the app automatically. Hence dynamic strings with require syntax are not possible.

require() intentionally don't support dynamically generated image names because it makes it very hard to manage assets over time.

Here is an example or alternate way you can achieve what you want.

image.js

const images = {
  logos: {
    kl: require('./logos/company_logo.png'),
    a1: require('./logos/car_logo.png'),
    kc: require('./logos/sma_logo.png'),
    nv: require('./logos/investment_logo.png'),
    other: require('./logos/other_logo.png'),
  }
};

export default images;

In your component file, you can import this image.js

import Images from './assets/images';

Then create one function to select image dynamically

imageSelect = imageselected => {
  if (imageselected === null) {
    return Images.logos.other;
  }

  const imageArray = {
    'KL': Images.logos.kl,
    'A1': Images.logos.a1,
    'KC': Images.logos.kc,
    'NV': Images.logos.nv,
    'Other': Images.logos.other,
  };

  return imageArray[imageselected];
};

Then in my components render function I call this new imageSelect function to dynamically assign the desired Image based on the value in the this.state.imageSelected:

render() {
  <img src={this.imageSelect(this.state.imageSelected)} />
}

The value passed into the imageSelect function could be any dynamic string or number as you prefer and accordingly, you can build your own logic in the function imageSelect.

Abhijeet Abnave
  • 801
  • 6
  • 16