1

I'm new to React JS and I'm not sure how to do a for loop to render something a variable number of times. This is my code:

<div className="product-selector__products">
    { this.props.products.sort(function(a,b) { return a.ranking - b.ranking }).map((p) => { 

        const className = "product" + ((this.props.selectedProductIds.indexOf(p.id) !== -1) ? " product--selected" : "");
        const descriptionHtml = { __html: p.description };
        const nameHtml = { __html: p.name };

        return (
            <div className={className} key={ p.id } onClick={this.onProductClick.bind(this, p.id)}>

                <div className="product__image">
                    <img src={`/~/media/Bayer CropScience/Country-United-States-Internet/Comparison Tool/img/logos/${p.id}_sm.png`} alt={p.name} />
                </div>
                <div className="product__info">
                    <div className="product__name" dangerouslySetInnerHTML={nameHtml}></div>
                    <div className="product__description" dangerouslySetInnerHTML={descriptionHtml}></div>
                </div>
                <div className="product__message" ref={ p.id }>
                    <div className="product__message-tooltip">Please remove a product<br/>before adding another</div>
                    <div className="product__message-triangle-down"></div>
                </div>
            </div>     
        );  
    }) }

    /* Here I want to render <div className="product product--empty"> </div> a variable number of times*/

</div>

It generates a grid of product items, with 4 items per row.

I need to add empty divs onto the end of the last row so that each row has the same number of divs in it.

So if this.props.products.length == 7 I need 1 empty div, and if I have 5 products I need 3 empty divs, etc.

The script i want is this:

let remainder = 4 - (this.props.products.length % 4);
  for (let i = 0; i < remainder; i++){
    return ( <div className="product product--empty"> </div> )
  }  

I'm not sure how to properly put this into the code-block though.

4
  • 1
    Why not to this.props.products.slice(0, 4).map? Commented Dec 1, 2016 at 15:35
  • 2
    Your desired code will always complete just the first run in the loop, as you have a return instruction. Commented Dec 1, 2016 at 15:36
  • @elmeister would that get the remainder that I need? Could you write a more detailed snippet? Commented Dec 1, 2016 at 15:40
  • this.props.products.slice(-this.props.products.length % 4, this.props.products.length % 4 ? undefined : 0).map(() => <div className="product product--empty"/>), maybe it's better to assign this.props.products.length % 4 to variable first Commented Dec 1, 2016 at 16:10

1 Answer 1

2

I've just modified a little Your code.

renderRemainders() {
  let products = []
  let remainder = 4 - (this.props.products.length % 4)

  for (let i = 0; i < remainder; i++){
    products.push( <div className="product product--empty"> </div> )
  }

  return products
}

And just put

 { this.renderRemainders() }

somewhere in Your 'render' function.

Also, could You say something about why you need to render these empty rows?

Sign up to request clarification or add additional context in comments.

2 Comments

I need them for styling purposes, to keep everything positioned evenly. They're just spacers.
So how about putting them into some container, and just set static height to that container? :) Creating 'fake nodes' is basically not so great idea.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.