Hamed Minaee
Hamed Minaee

Reputation: 2560

How to import the image dynamically

I use url-loader to load images in my webpage by converting them in byte.

Here is my normal case which works fine:

import React from 'react';
import accountImg from '../../../../images/setting/account.png';
const Account =(props) => (
<div>
    <img src={accountImg} className="img-responsive" style={{"width":"100%"}} ></img>
</div>
 );
export default Account;

But what if I need a dynamic import:

    render() {
    return (
               <img  src={ "/images/headers/"+this.props.newsChannel.removeAllSpaces().toLowerCase()+".png"}></img>

    );

So specifically for this case:

src={ "/images/headers/"+this.props.newsChannel.removeAllSpaces().toLowerCase()+".png"

How can I import the png dynamically?

Upvotes: 2

Views: 3020

Answers (2)

Matt Carlotta
Matt Carlotta

Reputation: 19762

Option 1: Lazy load the images from within a reusable class component. You can load images by their name and a relative path to your images folder from this component; however, it still requires that all of the images be present upon runtime and during production compilation. In other words, what you have in your images folder is what you're stuck using.

import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';

class LazyLoadImage extends Component {
  state = { src: '', err: '' };

  componentDidMount = () => {
    this.loadImage();
  };

  loadImage = async () => {
    try {
      const { default: src } = await import(/* webpackMode: "lazy" */ `../../images/headers/${this.props.name}.png`);
      this.setState({ src });
    } catch (err) {
      this.setState({ err: err.toString() });
    }
  }; 

  render = () => (
    <Fragment>
      <h5>Lazy Load Images</h5>
      <img src={this.state.src} alt="example.png" />
      {this.state.err && <p>{this.state.err} </p>}
    </Fragment>
  );
}

LazyLoadImage.propTypes = {
  name: PropTypes.string.isRequired,
};

export default LazyLoadImage;

Option 2: The ideal option would be to build an image microservice or use a CDN that handles all things images. All that you would need to do is store a link to the image, for example, you'd store a string like: http://localhost:4000/uploads/image.ext (if you use a CDN, it'd be something like: https://i.sstatic.net/sq10x.png). The client would retrieve this string (from a database) and make a GET request to this link (when a HTTP string is added to an img element's src property -- <img src="http://example.com/img.png" /> -- it automatically makes a GET request to that address).

This offers the most flexibility because you can add/remove/substitute images very easily by simply changing this string (it also doesn't need to be in your images folder to be loaded); it also offers the best performance -- as it offloads all the image work from the client to the dedicated service.

import React, { Fragment } from 'react';
import PropTypes from 'prop-types';

const ImageFromCDN = ({ src }) => (
  <Fragment>
    <h5>Image From CDN</h5>
    <img src={src} alt="example.png" />
  </Fragment>
);

ImageFromCDN.propTypes = {
  src: PropTypes.string.isRequired,
};

export default ImageFromCDN;

Upvotes: 4

dadwic
dadwic

Reputation: 378

You should be use redux/context to wrap your Account function component with new states and change image src realtime

Upvotes: 0

Related Questions