Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react.js every nth item add opening tag or closing tag

I'm having trouble with this logic since react/jsx does not allow for non closing tags to be added to an array/child component. For example with bootstrap css I want to add a row for every 4 columns.

So the logic is as follows:

Add a opening row ex: <div className="row">, then loop inside this row and every loop append a column ex: <div className="column>{this.data}</div> when the loop reaches 4 check with if(i % 4 == 0) and add a closing </div> tag while adding new row tag <div className="row">;

The code below would work in another language but in react this is not doable since we push a closing tag and a opening tag (which is invalid jsx):

generateColumns(columns) {
 let newColumns = [];

 columns.forEach(function(column, idx) {
  newColumns.push( <div className="column"> some data </div> );

  if (idx % 4 == 0) {
   // Here we end the row and start a new row, works in any other language.
   newColumns.push( </div> <div className="row"> );
  }
 });

 // This array now has the proper tags for opening a row every 4th item and closing it.
 return newColumns;
},
render() {
   return (
     <div className="row">
       {this.generateColumns(this.props.columns)}
     </div>
   )
}

The expected output would be:

<div class="row">
  <div class="column">
   Some data
  </div>
  <div class="column">
   Some more data
  </div>
  <div class="column">
   Other data
  </div>
  <div class="column">
   Something else
  </div>
</div>
<div class="row">
  <div class="column">
   Some data
  </div>
  <div class="column">
   Some more data
  </div>
  <div class="column">
   Other data
  </div>
  <div class="column">
   Something else
  </div>
</div>

//the above would be repeated and new rows would appear every 4 columns.

like image 201
AntonB Avatar asked Mar 30 '16 20:03

AntonB


People also ask

What is ${} In React?

the ${} is the syntax for variables (or other code to be executed) inside template literals (`).

How do I map for every two elements for React?

short answer. Transform model, then inject in View.

Does br need a closing tag React?

But in React, the <br> is used differently, which means the br tag will be used as a self-closing tag, whereas in HTML, it can be used just like <br> to break the section.

Is it OK to use window object in React?

The window object is the normal DOM object. It is always available and safe to use (unless you are server side rendering).


2 Answers

render() {
   const rows = array_chunk(this.props.columns, 4)
   return (
     {
       rows.map((row) => (
         <div className="row">
         {
           row.map((col) => (
             <div className="col">{ col }</div>
           ))
         }
         </div>
       ))
     }
   )
}

An example array_chunk (I recommend that you use lodash)

module.exports = function chunks(arr, size) {
  if (!Array.isArray(arr)) {
    throw new TypeError('Input should be Array');
  }

  if (typeof size !== 'number') {
    throw new TypeError('Size should be a Number');
  }

  var result = [];
  for (var i = 0; i < arr.length; i += size) {
    result.push(arr.slice(i, size + i));
  }

  return result;
};
like image 52
thangngoc89 Avatar answered Oct 15 '22 03:10

thangngoc89


I actually just used arrays and react handled fine the rendering.

render() {
    let rows = [],
        cols = []
    let index = 0
    const totalCols = 20;

    for (index; index < totalCols; index++) {
        cols.push(<div class="col" key={index}/>)
        if ((index + 1) % 4 == 0) {
            rows.push(
                <div class="row" key={index}>
                    {cols}
                </div>
            )
            cols = []
        }
    }
    return (
        <div class="container">
            {rows}
        </div>
    )
}
like image 44
Alejandro Moreno Avatar answered Oct 15 '22 04:10

Alejandro Moreno