Reputation: 267
Hello i search solution for open tag in loop and close it all the 3 iteration. The goal is to create a grill based on container row and col. My problem is I do not know how to do.
Exemple :
render(){
const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]
let arrayEl = [];
let count = 1;
for ( let i = 0; i < arrayName.length; i++ ) {
let name = arrayName[i]
if (count === 1) {
arrayEl.push(<div className="row">);
arrayEl.push(<p className="col">{name}</p>);
count ++;
continue;
}
if (count === 3) {
arrayEl.push(<p className="col" >{name}</p>);
arrayEl.push(</div>);
count = 1;
continue;
}
}
return (<div className="container">{arrayEl}</div>)
}
and the result wanted is :
<div className="container">
<div className="row">
<div className="col">john</div>
<div className="col">bob</div>
<div className="col">joe</div>
</div>
<div className="row">
<div className="col">mat</div>
<div className="col">toto</div>
<div className="col">tata</div>
</div>
</div>
thank you for some help
EDIT
The problem is we can't add someone element or componant without close it.
is Bad :
arrayEl.push(<div className="row">)
is good :
arrayEl.push(<div className="row"/>) or arrayEl.push(<div className="row"></div>)
Upvotes: 0
Views: 68
Reputation: 2799
You can't push HTML elements in parts, e.g.
arrayEl.push(<div>)
arrayEl.push(</div>)
You have to push the elements from start to end, e.g.
arrayEl.push(<div>{children}</div>)
Therefor you need to instantly output all cols
in row
, like the code example below.
render() {
const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"];
let rows = [];
let currentCols = [];
for (let i = 0; i < arrayName.length; i++) {
let name = arrayName[i];
currentCols.push(<div className="col" key={i}>{name}</div>);
if ((i+1) % 3 === 0) {
rows.push(<div className="row" key={i}>{currentCols}</div>);
currentCols = [];
}
}
rows.push(currentCols);
return (<div className="container">{rows}</div>)
}
Instead of using a count
variable, I just used the i
variable from your loop and checked whether or not (i + 1)
is dividable by 3: % 3 === 0
. If that is the case, it means you already have 3 cols in your row; We can push the currentCols
to the rows
array and empty it.
Upvotes: 1
Reputation: 1800
Ok, so you have to change the logic on your loop in order to get the result you want. Here's what I made as an example with JavaScript. You just need to adapt it with your component.
const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"];
let arrayEl = [];
for (let i = 0; i < arrayName.length; i++) {
let name = arrayName[i];
if ((i % 3) == 0) {
arrayEl.push(`<div className = "row">\n`);
}
arrayEl.push(`<p className = "col">${name}</p>\n`);
if (((i + 1) % 3) == 0) {
arrayEl.push(`</div>\n`);
}
}
console.log(`<div className="container">\n ${arrayEl.join(' ')}</div>`);
Upvotes: 0
Reputation: 45106
The problem with your approach is that JSX
is not html so </div>
expression is invalid.
Imperative approach for the sake of completeness. :)
BTW you need keys.
render(){
const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]
let arrayEl = [];
let row = [];
const batchSize = 3
for ( let i = 0, i < arrayName.length, i++ ) {
const name = arrayName[i]
row.push(<div className="col" key={name}>{name}</div>)
// we have a full batch or the last element
if (row.length === batchSize || i === arrayName.length - 1) {
arrayEl.push(<div className="row" key={i/batchSize}>{row}</div>)
row = []
}
}
return (<div className="container">{arrayEl}</div>)
}
Upvotes: 0
Reputation: 3368
I would change your data from:
["john", "bob", "joe", "mat", "toto", "tata"]
// to
[["john", "bob", "joe"], ["mat", "toto", "tata"]]
Checkout https://lodash.com/docs/4.17.11#chunk for example of that
And then you can nest 2 .map
to replicate the structure in JSX:
const chunk = (arr, chunckSize) => arr.reduce((chunks, value, index) => {
const chunckIndex = Math.floor(index / chunckSize)
const c = chunks[chunckIndex] || (chunks[chunckIndex] = [])
c.push(value)
return chunks
}, [])
render() {
const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]
return (
<div className="container">
{chunk(arrayName, 3).map(names => (
<div className="row">
{names.map(name => <div className="col">{name}</div>)}
</div>
))}
</div>
)
}
Upvotes: 1