I'm using also ReduxLazyScroll
for infinite scroll effect and it worked but before it was just ul -> li
list. Now I want my app to generate 3 cards one beside another in bootstrap-grid style, like so:
<Row>
<Col sm="4">.col-3</Col>
<Col sm="4">.col-3</Col>
<Col sm="4">.col-3</Col>
</Row>
And I have some logic problem, which I can't wrap my head around.
So there is the code of parent component ( BeerListingScroll
) :
import React, { Component } from 'react';
import { Container, Row, Col } from 'reactstrap';
import ReduxLazyScroll from 'redux-lazy-scroll';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchBeers } from '../../actions/';
import BeersListItem from '../../components/BeersListItem';
import ProgressIndicator from '../../components/ProgressIndicator';
class BeerListingScroll extends Component {
constructor(props) {
super(props);
this.loadBeers = this.loadBeers.bind(this);
}
loadBeers() {
const { skip, limit } = this.props.beers;
this.props.fetchBeers(skip, limit);
}
render() {
const { beersArray, isFetching, errorMessage, hasMore } = this.props.beers;
return (
<Container>
<ReduxLazyScroll
isFetching={isFetching}
errorMessage={errorMessage}
loadMore={this.loadBeers}
hasMore={hasMore}
>
{beersArray.map(beer => (
<Row>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
</Row>
))}
</ReduxLazyScroll>
</Container>
);
}
}
function mapStateToProps(state) {
return {
beers: state.beers,
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ fetchBeers }, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(BeerListingScroll);
So I'm using beersArray.map helper and I know that that logic doesn't make sense inside map
:
<Row>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
</Row>
because I'm loading each beer
element 3 times and then it looks like that ->
img
The question is: How should I refactor that code to get first, second and third array element in the first row, 4th, 5th, 6th in the second row etc?
Desired outcome:
And here you have child component ( BeerListItem
)
import React from 'react';
import {
Card,
CardImg,
CardBody,
CardTitle,
CardSubtitle,
Button,
} from 'reactstrap';
const BeerListItem = ({ beer }) => (
<div>
<Card>
<CardImg top width="100%" src={beer.image_url} alt="beer" />
<CardBody>
<CardTitle>{beer.name}</CardTitle>
<CardSubtitle>{beer.tagline}</CardSubtitle>
<Button>More details</Button>
</CardBody>
</Card>
</div>
);
export default BeerListItem;
And full project on github - > Link to github
If you want to do this you could group them together in 3's in a nested array, so instead of [beer1,beer2,beer3,beer4,...]
you have [[beer1,beer2,beer3],[beer4,..,..],...]
then you can iterate them in groups, with a row per beer group and a column per beer in that group:
beerGroupsArray.map(beerGroup => (
<Row>
{
beerGroup.map(beer => {
<Col xs="12" sm="4">
<BeersListItem key={beer.id} beer={beer} />
</Col>
})
}
</Row>
))}
That's just one example of how to do it though, based on your data and use case there might be a cleaner, more robust method.