React - Create nested components with loops

To render a list of elements inside JSX, you can do something like that:

render() {
    return <div>
        {
            [1,2,3].map ( (n) => {
                return this.renderSquare(n)
            })

        }
    </div>;
}   

Just wrap your array of components into {} in your JSX.

To clarify a bit, this is the same logic of:

return <div>
    {
        [
            <h1 key="1">Hello 1</h1>,
            <h1 key="2">Hello 2</h1>,
            <h1 key="3">Hello 3</h1>
        ]           
    }
</div>;

Note that everytime you render an array of components, you must provide a key prop, as pointed here.

Also, if you want simply print row value in your render function, you should replace:

index.forEach(function(row){
    board.push(() => {
        return(
            <div>{row}</div>
        );
    });
})

with:

index.forEach( (row, index) => {
    board.push(<div key={index}>{row}</div>)
})

or, yet, replacing forEach and push with map:

board = index.map( (row, index) => <div key={index}>{row}</div> )

EDIT I created a fiddle with a 9x9 board using your code as a base: https://jsfiddle.net/mrlew/cLbyyL27/ (you can click on the cell to select it)


I see you too are doing the JS React tutorial! Here's what I did, but I'm working on this because there has to be a good way to give each of these individual keys.

I ran into the same issue you were running into where the X's were drawn into 3 squares, and the reason that happens is because when you were rendering squares, some of the "i's" were duplicated. So there were multiple Squares with the "i" of 2 for example (at least that was the case in my issue).

So each Square has an index right? [0,1,2,3,4,5,6,7,8].

First we need to find how these are related in a way that we can render them into rows! So, in your example you have index1 and index2, which I assume will refer to the x and y coordinates of the Square in the Board. Re-writing the array above we come to: [{0,0}, {1,0}, {2,0}, {0,1}, {1,1}, {2,1}, {0,2}, {1,2}, {2,2}] using {x,y} format. How can we use these values (which we would get from your index1 and index2 in order to get the original array of values that we started with [0,1,2,3,4,5,6,7,8]?

What I did was 3 * x + y (or in a loop, 3 * i + j). This way each square has a unique "i" value associated with it.

After I set up my loops I used this SO post to correctly return the elements I created from a separate function (in a poor attempt to keep my code cleaner).

This is what I ended up with, but I need to make sure to set the keys correctly which is actually how I stumbled onto this post:

createSquares() {
  let rows = [];
  for(var i = 0; i < 3; i++){
    let squares = [];
    for(var j = 0; j < 3; j++){
      squares.push(this.renderSquare(3*i+j));
    }
    rows.push(<div className="board-row">{squares}</div>);
  }
  return rows;
}

Then my render function in Board looks like this:

render() {
  return (
    <div>
      {this.createSquares()}
    </div>
  );
}