JKhan
JKhan

Reputation: 1297

Looping an array to list items

In my frontend Reactjs app, I upload multiple images at the same time and save the urls in an array. When trying to loop an array which contains url to display on website, it shows each image in a separate box (which is good). However, when I click on a single image, it renders all the image urls in the array as per console log.

When I click a single image this shows up in console log:

http://192.168.22.124:3000/source/5102018114022AM-pexels-photo.jpg http://192.168.22.124:3000/source/5102018114022AM-redhat.jpg

handleClick() {
    this.setState({ isToggleOn: !this.state.isToggleOn})
}

render() {
const { name, fileExt, pic } = this.state;
var img = [];
for (var i = 0; i < pic.length; i++) {
  console.log(pic[i]);
    img.push(<a style={{width: 200, height: 250}} key={i} className={'tc ' + change + ' dib br3 ma2 pa2 grow bw2 shadow-5'} onClick={this.handleClick}>
      <div key={i}>
      <img style={{width: 175, height: 175}} className='tc br3' alt='robots' key={i} src={`${pic[i]}`}/>
      </div>
      </a>)
};

  return (
    isToggleOn && fileExt !== 'mp4' ?
    <div>
    { img }
    </div>

Upvotes: 1

Views: 92

Answers (1)

Austin Greco
Austin Greco

Reputation: 33554

Right now you are console.loging inside the loop in your render function. So whenever the content is rerendered, it will loop through and console.log multiple times. Because your handleClick method is calling setState, the component will be rerendered, which calls the render() function again and then console.log in the loop.

It sounds like what you want is it to only console.log the item you click on. If that's the case, then you would put your console.log inside the handleClick method which you would pass the parameter to:

onClick={() => this.handleClick(p)}

Also a much better way to do this is to use .map like below:

handleClick(url) {
  console.log(url);
  this.setState({ isToggleOn: !this.state.isToggleOn});
}

render() {
  const { name, pic } = this.state;
  return (
    <div>
      {pic.map((p, i) => (
        <a style={{width: 200, height: 250}} key={p} className={'tc ' + change + ' dib br3 ma2 pa2 grow bw2 shadow-5'} onClick={() => this.handleClick(p)}>
          <div>
            <img style={{width: 175, height: 175}} className='tc br3' alt='robots' src={p}/>
            <h2 style={{position: "absolute", top: 185, bottom: 0, right: 0, left: 0}} className='f6 measure-narrow lh-copy'>{name[i]}</h2>
          </div>
        </a>
      ))}
    </div>
  );
}

Also note: you only need key= on the outer element inside a loop.

Upvotes: 1

Related Questions