1

I'm using srcSet for changing my images at a certain width. This also works fine but I would like to set the image path/source dynamically instead of hardcoding the values in my source code. Does anyone have any suggestions how I could do this?

For example:

this.props.personas[this.state.index].images[0].mediaSize

I have a bin available here. Feel free to edit it.

Tagc
  • 8,736
  • 7
  • 61
  • 114
mY777
  • 229
  • 3
  • 7
  • 19

2 Answers2

2

You can use map on this.props.personas[this.state.index].images to create the sources dynamically.

Like this:

<picture>         
    {this.props.personas[this.state.index].images.map((el,i) => {
        return  <source
                    key={i}
                    media={el.mediaSize}
                    srcSet={el.imageUrl} 
                />
    })}
    <img src={this.props.personas[this.state.index].defaultImage} />
</picture>

Check working pen.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
1

You can use map() to iterate through your images:

<picture> 
  {this.props.personas[this.state.index].images.map((item, i) => {
    return (
      <source
        key={i}
        media={item.mediaSize}
        srcSet={item.imageUrl}
      />
    );
  })}
  <img src={this.props.personas[this.state.index].defaultImage} />
</picture>

Check out the full demo below, or a modified version of your bin, here.


Demo

class Personas extends React.Component {
  
  constructor(props, context, images) {
    super(props);
    this.state = {
      index: 0
    };
  }

  changePerson  (e, index)  {
    e.preventDefault();
    this.setState({
      index: index
    });
  }

  render() {
    const thumbs = this.props.personas.map((current, idx) => {
      return (
        <a key={idx} className={'persona-link ' + (this.state.active ? 'active-link' : '')} >
          <div >
            <img src={current.thumbnail} onClick={(event) => this.changePerson(event, idx)}/>
          </div>
        </a>
      )
    });
    return (
      <div className='personas'>
        <picture> 
          {this.props.personas[this.state.index].images.map((item, i) => {
            return (
              <source
                key={i}
                media={item.mediaSize}
                srcSet={item.imageUrl}
              />
            );
          })}
          <img src={this.props.personas[this.state.index].defaultImage} />
        </picture>
        <span className='personas-thumbnail'>
          {thumbs}
        </span>
      </div>
    )
  }
}
  
ReactDOM.render(<Personas 
     personas =  {[
      {
        thumbnail: '//via.placeholder.com/90x90',
        defaultImage: '//via.placeholder.com/768x400',
        images: [
          {
            imageUrl: '//via.placeholder.com/1024x400',
            mediaSize: "(min-width: 500px)"
          },
          {
            imageUrl: '//via.placeholder.com/1027x400',
            mediaSize: "(min-width: 600px)"
          }
        ]
      }
    ]}
  
  />, document.querySelector('#app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Useful links

Community
  • 1
  • 1
Chris
  • 57,622
  • 19
  • 111
  • 137