简体   繁体   中英

JSX breaks ... Looping over an array with map generating conditional JSX elements

I am having issues trying to build a custom component with a looping array that conditionally renders different elements. That component contains special classNames for generating a grid of 3 elements per row, independently of the number of parameters passed to the component.

I am using map for looping through a conditional index where I render conditionally the first element (for opening), normal elements, every 3 elements (for closing column and opening again), and the final element.

    let optionsLength = this.props.options.length;
    let options = []

    this.props.options.map((option, index) => {
          if (index === 0) {
            options.push(
          <div className="column is-one-third">
          ...
          // other conditionals explained below

The problem comes trying to find a way where every 3 elements I need to close and open the parent <div> .

I would like to close the </div> tag and open a new column div <div className="columns sub"> before just appending the element. That iteration cannot be closed in that same conditional as the styles would break an there is more logic that depends on the following elements. But on the other side, JSX breaks.

Here is some pseudocode of what I would love to achieve:

<div classname="columns"> // <-- ideally, rendered with the same element
  <div>...</div> //<-- 1st element
  <div>...</div>// <-- 2nd element
  <div>...</div>// <-- 3rd element, so we add the following 2 lines
</div> <-- 3rd element
<div className="columns"> //<-- 3rd element
<div>...</div> //<-- 4rd element
...
<div>....</div>//<-- last element
</div>// <-- last element

PS I am using bulma for generating the columns grid.

Assuming this.props.options is [1,2,3,4,5,6,7] , I declare this method for the component:

    treatArray = arr => {
      let masterArray = []
      // Will a new array of arrays with 3 items
      while (arr.length) masterArray.push(arr.splice(0, 3));

      return (
        <div>
          {masterArray.map(setOf3 => (
            <div classname="columns">
              {setOf3.map(singleCol => (
                <div className="column is-one-third">{singleCol}</div>
              ))}
            </div>
          ))}
        </div>
      );
    };

And then invoke this function in your render :

render(){
    return(
     //.
     //.
        { this.treatArray(this.props.options) } 
     //.
     //.
    )
}

Here is a working codesandbox .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM