Fullhdpixel
Fullhdpixel

Reputation: 813

NativeBase: Generate Columns in Row

I want to map a number of items in an array to a grid of 3 columns for each row. Right now I have the entire grid hardcoded, but it should be trivial to do this automatically.

This is what the end result should look like:

<Grid>  
  <Col> 
    <Row>Cel 1</Row>
    <Row>Cel 2</Row>
    <Row>Cel 3</Row>
  </Col>
  <Col> 
    <Row>Cel 4</Row>
    <Row>Cel 5</Row>
    <Row>Cel 6</Row>
  </Col>
  <Col> 
    <Row>Cel 4</Row>
    <Row>Cel 5</Row>
    <Row>Cel 6</Row>
  </Col>
  <Col> 
    <Row>Cel 4</Row>
    <Row>Cel 5</Row>
    <Row>Cel 6</Row>
  </Col>
  <Col> 
    <Row>Cel 4</Row>
    <Row>Cel 5</Row>
    <Row>Cel 6</Row>
  </Col>          
</Grid>

Here is the render method, which does not do much atm. Im not sure how to even start on this issue.

render() {
    let images = [
      Images.grid1,
      Images.grid2,
      Images.grid3,
      Images.grid4,
      Images.grid5,
      Images.grid6,
      Images.grid7,
      Images.grid8,
      Images.grid9
    ];

return images.map(link => {
    return (
      <Grid>
       <Row>
        <Col>link</Col>
        <Col>link</Col>
        <Col>link</Col>
       </Row>
       <Row>
        <Col>link</Col>
        <Col>link</Col>
        <Col>link</Col>
       </Row>
      </Grid> 
      );
   });
}

Upvotes: 2

Views: 6020

Answers (1)

Pakpoom Tiwakornkit
Pakpoom Tiwakornkit

Reputation: 2939

Your images array should be stored in state or props whenever possible because when your images get updated(insert, remove or delete), React will rerender your component again.

And your Images array should be re-structured as an example below in order to render with three column in each row.

gridArray = [
    [image1, image2, image3],
    [image4, image5, image6],
    [image7, image8, image9],
];

Take a look at my working example on CodeSandbox through this link https://codesandbox.io/s/jly9332lzy.

In the example on CodeSandbox I change the component from Grid to div, Row to ul and Col to li to avoid errors on the online sandbox. You just change components to Grid, Row and Col, edit code a bit to adapt to your code and everything will work.

Below is my code that solves your problems

import React from "react";
import { render } from "react-dom";

class YourComponent extends React.Component {
  constructor(props) {
    super(props);
    // Your source data
    this.state = {
      images: [
        "Image 1",
        "Image 2",
        "Image 3",
        "Image 4",
        "Image 5",
        "Image 6",
        "Image 7",
        "Image 8",
        "Image 9",
      ]
    };
  }

  // this method will return structured array like this.
  // gridArray = [
  //    [image1, image2, image3],
  //    [image4, image5, image6],
  //    [image7, image8, image9],
  // ];
  imagesArrayToGridArray(totalColumns) {
    let gridArray = [[]];

    let countColumns = 1;
    for (var i = 0; i < this.state.images.length; i++) {
      gridArray[gridArray.length - 1].push(this.state.images[i]);
      if (countColumns <= totalColumns) {
        countColumns++;
      }
      if (countColumns > totalColumns && i !== this.state.images.length - 1) {
        countColumns = 1;
        gridArray.push([]);
      }
    }

    return gridArray;
  }

  // return React Components like
  // <Row>
  //   <Col>Image 1</Col>
  //   <Col>Image 2</Col>
  //   <Col>Image 3</Col>
  // </Row>
  // <Row>
  //   <Col>Image 4</Col>
  //   <Col>Image 5</Col>
  //   <Col>Image 6</Col>
  // </Row>
  // <Row>
  //   <Col>Image 7</Col>
  //   <Col>Image 8</Col>
  //   <Col>Image 9</Col>
  // </Row>
  renderGrid(gridArray) {
    return gridArray.map(row => (
      <Row>{row.map(col => (<Col>{col}</Col>))}</Row>
    ));
  }

  // render
  render() {
    let gridArray = this.imagesArrayToGridArray(3);
    return <Grid>{this.renderGrid(gridArray)}</Grid>;
  }
}

render(<YourComponent />, document.getElementById("root"));

And that's it, now everything will work.

Upvotes: 3

Related Questions