Home > Mobile >  .map() to generate a grid in react
.map() to generate a grid in react

Time:10-07

I am trying to generate a grid in the function createGrid() by iterating through rows and columns then storing the values in grid[] and display a cell for each item in the array.

componentDidMount() {
    const grid = createGrid();
    this.setState({ grid });
    //console.log(this.state.grid)
  }

  render() {
    //console.log(this.state.grid)
    return (
      <div>
        {this.state.grid.map((row, rowIdx) => {
          return <Node />
        })}
      </div >
    );
  }
}



const createGrid = () => {
  const grid = [];
  for (let row = 0; row < 15; row  ) {
    const currentRow = [];
    for (let col = 0; col < 50; col  ) {
      currentRow.push(createNode(row, col));
    }
    grid.push(currentRow);
    grid.push(currentRow)
    console.log(grid);

  }
  return grid;
};

const createNode = (row, col) => {
  return {
    row,
    col,
  };
  console.log(row);
  console.log(col);
};

I want the grid to look something like this

But the program only displays this and i don't whyenter image description here

CodePudding user response:

This component is completely untested, but should do what you want.

.grid {
    display: grid;
    border-top: 1px solid var(--border-color);
    border-left: 1px solid var(--border-color);
}

.grid > div {
    border-right: 1px solid var(--border-color);
    border-bottom: 1px solid var(--border-color);
}
function Grid({rows, columns, cellWidth, cellHeight, borderColor}) {
    return (
        <div
            className="grid"
            style={{
                gridTemplateColumns: `repeat(columns.length, ${cellWidth}px)`,
                gridTemplateRows: `repeat(rows.length, ${cellHeight}px)`,
                '--border-color': borderColor,
            }}
        >
            {Array.from({length: rows * columns}, (_, index) => (
                <div key={index} />
            ))}
        </div>
    )
}

Grid.propTypes = {
    rows: PropTypes.number.isRequired,
    columns: PropTypes.number.isRequired,
    cellHeight: PropTypes.number.isRequired,
    cellWidth: PropTypes.number.isRequired,
    borderColor: PropTypes.string.isRequired,
}

If you just want to draw a grid and not place anything inside it, a more efficient approach would be to render a <canvas /> and draw a grid inside it.

CodePudding user response:

I don't know how the Node element looks like. But.

My approach needs few lines of css to achieve this. Also. U are creating 2D array in createGrid function and then u are mapping throught it like u would map throught 1D array.

My brainfart solution looks like:

Render method in the class component.

  render() {
    //console.log(this.state.grid)
    return (
      <div>
        {this.state.grid.map((row, rowIdx) => {
          return <Node />
        })}
      </div >
    );
  }
}



const createGrid = () => {
  const grid = [];
  for (let row = 0; row < 15; row  ) {
    const currentRow = [];
    for (let col = 0; col < 50; col  ) {
      currentRow.push(createNode(row, col));
    }
    grid.push(currentRow);
    grid.push(currentRow)
    console.log(grid);

  }
  return grid;
};

const createNode = (row, col) => {
  return {
    row,
    col,
  };
  console.log(row);
  console.log(col);
};

Notice I am mapping through row, creating div with class row and inside the div I am mapping through the row to access to column.

Then I have created the Node class component (I pref functional but I've created class for u since u are using class component in the post).

It looks like this

import React from 'react';

class Node extends React.Component {
  // props has x and y number.
  // x stands for row and y for column.
  // (imagine the X and Y coordinates with origin in the upper-left corner of the window and x coordinate directs right and y directs going down)
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div class='node'>
        <div className='node-content'></div>
      </div>
    );
  }
}

export default Node;

Finally I have added css for the classes I have used

.node-content {
  display: flex;
}

.row {
  display: flex;
}

.node {
  border: 1px solid black;
  width: 30px;
  height: 30px;
}

And the final result looks like this

enter image description here

Important note: U push the row in to the grid array twice.

  • Related