rodcunha
rodcunha

Reputation: 431

ReactJS: How to add JSX IMG SRC paramenter dynamically from state?

I can't figure out how to load the img src dynamically in ReactJS.

As the user navigates the page I'm updating state from a json file loading among other things the hero images and alt tags from the json. The alt attribute works fine but I have been trying to load the img src="" dynamically without any success.

I've seen here a solution where we use require and template literals but that hasn't worked for me, see below:

<img src={require(`${this.state.activePageData.url}`)}

this code returns an error 'cannot find module undefined'.

According to some posts here I should remove the node_modules folder and run npm install, I have done that too with no results.

If I try to use the state directly (<img src={this.state...} />) it renders the page but the image isn't loaded, on dev tools if I check the element, it has the correct path in the source element of the compiled HTML but yet it doesn't render the image. On the network tab it returns an element with the correct name of the image and status 200 OK but doesn't display the image on the Application tab when clicked on this element.

I'm new to ReactJS and don't know much about it. I've tried to use the debugger to figure this out but couldn't. Would anyone be able to lend a hand? Thank you.

import React, {Component} from 'react';
import propTypes from 'prop-types'
import PageData from '../PageInfo.json';

class Hero extends Component {
  state = {
    activePage: '',
    activePageData: [],
    PageData: PageData
  }

componentDidMount = () => {
 switch (this.props.page) {
   case 'homepage':
    this.setState({activePage: ''})
    this.setState({activePage: this.props.page})
    this.getBackgroundImage('Homepage')
    break;
  case 'about':
    this.setState({activePage: ''})
    this.setState({activePage: this.props.page})
    this.getBackgroundImage('About')
    break;
  default:
    console.log("There's no such page")
    break;
  }
}

 getBackgroundImage = (page) => {
   this.state.PageData.Pages.forEach( e => {
     if ( e.PageName === page ) {
       this.setState({activePageData: ''})
       this.setState({activePageData: e }, () => {
       })
     }
   })
  }

render() {

 const styles = {
   bgStyle: {
     height: '100vh',
     width: 'auto',
     position: 'absolute',
     zIndex: '1',
     background: '#074481',
     backgroundSize: 'cover',
     backgroundPosition: '50% 50%'
  },
  imgStyle: {
    height: '100%',
    width: 'auto'
  }
}

return(
  <section className="cover fullscreen image-bg parallax">
      <div style={styles.bgStyle}>
        <img alt={this.state.activePageData.alt} style={styles.imgStyle} src={this.state.activePageData.url} /> </div>
      <div className="container v-align-transform">
          <div className="row">
              <div className="col-sm-12">
                  <h1 className="col-sm-12 large">Header</h1>
                  <h2 className="pl20">Title 2</h2>
          </div>
      </div>
    </div>
   </section>
  )
 }
}
Hero.propTypes = {
  page: propTypes.string.isRequired
}

export default Hero

Sorry, here's the JSON:

{
  "Pages": [
     {
       "id": 1,
       "title": "Home Page Title",
       "PageName": "Homepage",
       "url": "../img/hero-home.jpg",
       "alt": "alt text test",
       "description": "Home page desc test"
     },
     {
       "id": 2,
       "title": "About Page Title",
       "PageName": "About",
       "url": "../img/about-hero.jpg",
       "alt": "About Alt text",
       "description": "About page desc test"
     }
   ]
 }

Edit: Please note that the component Hero resides inside a components directory which will require the path for the image to be ../

Upvotes: 0

Views: 2073

Answers (1)

Boudewijn Danser
Boudewijn Danser

Reputation: 111

I thinks it's in your path to the img folder. ../img/ would put the folder outside of the public folder.

I got it to work by:

  • Putting images in my public/img folder with your names (hero-home.jpg / about-hero.jpg)
  • Changing ../img to ./img

Hope that helps.

Upvotes: 1

Related Questions