I'm following the React Js tutorial from the official site which helps us build a tic-tac-toe game. The square boxes are created by hardcoding all the squares as follows:
render(){
return (
<div>
<div className = "board-row">
{this.renderSquare(0)}
{this.renderSquare(1)}
{this.renderSquare(2)}
</div>
<div className = "board-row">
{this.renderSquare(3)}
{this.renderSquare(4)}
{this.renderSquare(5)}
</div>
<div className = "board-row">
{this.renderSquare(6)}
{this.renderSquare(7)}
{this.renderSquare(8)}
</div>
</div>
);
}
I managed to shorten the code by using a for loop as shown below:
render(){
let sqrRen = [];
for(let i = 0; i < 9; i=i+3){
sqrRen.push(<div className = "board-row">
{this.renderSquare(0+i)}
{this.renderSquare(1+i)}
{this.renderSquare(2+i)}
</div>);
}
return (
<div>
{sqrRen}
</div>
);
}
But I also want to generate the squares in each row using another for loop as follows:
render(){
let sqrRen = [];
for(let i = 0; i < 9; i=i+3){
sqrRen.push(<div className = "board-row">
{
for(let j=0;j<3;j++){
this.renderSquare(j+i)
}
}
</div>);
}
return (
<div>
{sqrRen}
</div>
);
}
but this is not working. I get the following error:
Any suggestions on how to go about using two for loops?
Since I was also looking for this, the accepted answer pointed me to the right direction. Though I made a slightly different implementation without lodash.
render() {
const rowCount = 3, colCount = 3;
return (
<div>
{[...new Array(rowCount)].map((x, rowIndex) => {
return (
<div className="board-row" key={rowIndex}>
{[...new Array(colCount)].map((y, colIndex) => this.renderSquare(rowIndex*colCount + colIndex) )}
</div>
)
})
}
</div>
);
}
You don't need to use the usual for
loops as they look very messy. Instead, you should utilize the new ES6 features and syntax to achieve a cleaner and more understandable approach.
The solution below renders a 3x3 tic-tac-toe board just fine:
import chunk from 'lodash/chunk';
const styles = { width: '40px', height: '40px', float: 'left', textAlign: 'center' };
return (
<div className="tic-tac-toe-container">
{chunk(new Array(9).fill(0), 3).map((item, itemIndex) => {
return (
<div key={itemIndex} className="row">
{item.map(col => <div className="col" style={styles}>COL</div>)}
</div>
)
})
}
</div>
);
Since I stuck at this additional problem for hours yesterday and finally arrived at this "two For loops" solution, let me share it here for upcoming react learners.
class Board extends React.Component {
renderSquare(i) {
return (
<Square
key={i} //prevent warning
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
/>
);
}
render() {
const row = [];
let k = 0; //key
for (let i = 0; i < 3; i++) {
const col = [];
for (let j = 0; j < 3; j++) {
col.push(this.renderSquare(3*i+j)); //push argument without {}, <>
k++;
}
row.push(<div key={k} className="board-row">{col}</div>);
}
return (
<div>
{row}
</div>
);
}
}
The most important part is to figure out how to assemble JSX syntax with push. Here "this.renderSquare(3*i+j)" will just return the element, so that's what we want. I personally think this is better than Array.prototype.map solutions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With