Search code examples
javascriptreactjsreact-bootstrap

React-Bootstrap variable number of Cols per Row based on breakpoint


Currently I have this code:

return(
<Container>
    {array.map(function(item, i) {
        if (i%4 == 0) {
            return(
                <Row key={i} xs="3" sm="4">
                {array.slice(i, i+4).map(function(item, i) {
                    return(
                    <Col key={i}>
                        <Card className={"card"}>
                            <Card.Body>
                            <Card.Text>{item.name}</Card.Text>
                            </Card.Body>
                        </Card>
                    </Col>);
                })}
                </Row>
            );
        }
    })}
</Container>);

To give some context - I am pulling a variable amount of data from a database into an array, and displaying them as cards. I am using a Container to display it in a Grid, consisting of x rows and y columns. However, for any screens larger than the xs breakpoint, I would like to display 4 items per Row, hence 4 Cols per Row. Once the xs breakpoint is hit, I would like to display 3 items per Row. However, the functionality right now isn't as I intended. Consider the following example:

A B C D
E F G H

becomes

A B C
D
E F G
H

instead of

A B C
D E F
G H

Would anyone be able to advise where or how I can get this fixed? In my search through the docs and online, I could not find any example which has a similar use-case (or maybe I'm not searching for the correct term). Any help would be great, thank you!


Solution

  • This is probably happening because you are using array.slice(i, i+4) and the function is taking 4 elements at a time.

    You may rather try :

    return(
      <Container>
        <Row key={i} xs="3" sm="4">
          {array.map(function(item, i) {
            return(
              <Col key={i}>
                  <Card className={"card"}>
                      <Card.Body>
                      <Card.Text>{item.name}</Card.Text>
                      </Card.Body>
                  </Card>
              </Col>
            );
            })}
        </Row>
      </Container>);
    

    Hopefully this will work (maybe a bit more manipulation).