Mapping a 2d array in React

Viewed 814

I have a simple component called GridSquare:

import React from 'react';
import './GridSquare.css'

const GridSquare = (props) => {
    
    return (
    <div className="empty-square">
    </div>
    )
}

export default GridSquare;

The css file of GridSquare is just making the div a simple gray square:

.empty-square{
    display: inline-block;
    height: 30px;
    width: 30px;
    background-color: #555;  
}

I'm trying to create a grid of these squares with a component called Grid. I'm having difficulties with mapping the 2d array. Mapping one dimensional array works fine but the 2d array just prints out empty divs.

import React from 'react';
import GridSquare from './GridSqure'

const GameGrid= () => {
    const gamegrid=new Array(20);
    for(let i =0; i<gamegrid.length; i++)
        gamegrid[i] = new Array(20);

    console.log(gamegrid);
    
    return(
        <div>
            {
            gamegrid.map((row)=> 
            {
                return (
                    <div>
                        {
                            row.map(() => <GridSquare/>)
                        }
                    </div>
                )})
            }
        </div>
    )
}

export default GameGrid;

What am I missing?

3 Answers

new Array(20) creates an array of 20 empty elements.
The map method ignores empty elements, so you should fill your array: gamegrid[i] = new Array(20).fill(null);

Why don't you have it this way:

{[...Array(20)].map(() => (
  <div>
    {[...Array(20)].map(() => (
      <GridSquare/>
    ))}
  </div>
))}

Instead of defining the dimensions of the grid outside in the GameGrid const, you explicitly create an array of 20, map through it, and create another array of 20 to get your 20X20 grid.

Note you can have the 20 as a variable like let size = 20, so this part [...Array(20)] becomes [...Array(size)]
This will give you the ability to dynamically change the grid size of your app

Initializing array that way isn't enough. You should also populate it's elements:

for(let i =0; i<gamegrid.length; i++) {
    gamegrid[i] = new Array(20);
    gamegrid[i].fill(1); // this is just an example value
}

Also, you should add keys to all the elements you are mapping:

return(
    <div>
        {
        gamegrid.map((row, i1)=> 
        {
            return (
                <div key={i1}>
                    {
                        row.map((el, i2) => <GridSquare key={i2} />)
                    }
                </div>
            )})
        }
    </div>
)
Related