Search code examples
reactjsimagelocal-storagedangerouslysetinnerhtml

DangerouslySetInnerHTML with a Local Image in React.JS


In react.js the code below is supposed to diaplay a local image a certain amount of times based on the number fed to the function on Line 6. In the actual program that number will change based on information being fetched from a remote server so I can't just hardcode it.

Line 22 calls the image the correct amount of times, but it displays the alternate text instead of the actual photo.

Line 23 calls the image perfectly. So, I know it's being imported correctly.

How do I get line 22 to display images and not just text?

import React from 'react'
import local_image from '../images/local_image.png'

export default class Album extends React.Component {

  displayXImages(num) { // line 6
    let x = 0
    let img_html = ''
    while (x < num) {
      img_html = img_html + "<img src={local_image.png} alt='local image' className='image' />" // line 10
      x = x + 1
    }
    
    return img_html // line 14
  }

  render() {
    const inner_html = displayXImages(3) // line 18

    return(
      <main>
        <div className='album' dangerouslySetInnerHTML={inner_html) /> // line 22
        <img src={local_image.png} alt='local image' className='image' /> // line 23
      </main>
    )
  }
}

Solution

  • Update #1:

    import React from "react";
    import local_image from '../images/local_image.png'
    
    export default class Album extends React.Component {
      displayXImages(num) {
        // line 6
        let x = 0;
        let img_html = "";
        while (x < num) {
          img_html =
            img_html +
            `<img src=${local_image} alt='local image' className='image' />`; // EDITED: Template literal string with local_image being casted to its value
          x = x + 1;
        }
    
        return { __html: img_html }; // EDIT: dangeruslySetInnerHTML accepts an object type containing __htmo prop that should hold ur HTML content
      }
    
      render() {
        const inner_html = this.displayXImages(3); // line 18
        
        return (
          <main>
            <div className="album" dangerouslySetInnerHTML={inner_html} />
          </main>
        );
      }
    }
    

    Different approach:

    I made this simple app taking advantage of Refs. It should translate to your needs.

    import React from 'react'
    
    export default class Album extends React.Component {
      constructor(props) {
        super(props);
        this.imageContainer = React.createRef();
      }
    
      setImageContainerContent() {
        const imgSRC = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/React.svg/250px-React.svg.png";
        if(this.imageContainer.current) {
          const newImgEl = document.createElement("img");
          newImgEl.src = imgSRC;
          newImgEl.alt = "Some image alt text"
          /*
           * would you remove everything else from the tree with every update??
           * if u shall >> this.imageContainer.current.innerHTML = "";
           *
           */
          this.imageContainer.current.appendChild(newImgEl);
        }
      }
    
      componentDidMount() {
        this.setImageContainerContent();
      }
    
      render() {
        return(
          <main>
            <div className='album' ref={this.imageContainer} />
          </main>
        )
      }
    }