Reputation: 4998
I'm well versed with Angular but not React. I want to display images in a row-col layout in such a way that no. of columns should be dynamic while the no. of rows should be adjusted accordingly. That means if the user gives 4(say) images and says that he wants 2(say) columns, then the grid layout should be 2X2. Pretty simple.
I'm setting the state in App.js
state = {
flowerCard: [
{
colCount: 3, // <-------------- this will decide number of columns
tiles: [
{
imageSource: '...',
text: 'White flower',
},
{
imageSource: '...',
text: 'Red flower',
},
{
imageSource: '...',
text: 'Purple flower',
},
{
imageSource: '...',
text: 'Purple flower',
},
],
},
],
};
...
<Card
colCount={this.state.flowerCard[0].colCount}
tiles={this.state.flowerCard[0].tiles}>
</Card>
Card.js
let localTiles = props.tiles;
let colCount = props.colCount;
return (
<div>
{localTiles.map((tile, index) => {
return (
<div>
<Row>
<Col md={4}>
<p>{tile.text}</p>
<Image
className="tile-image"
height={100}
width={300}
src={tile.imageSource}
alt="logo"
/>
</Col>
</Row>
</div>
);
})}
</div>
);
I've done similar thing in Angular using *ngFor
. Please help me achieve this in React. I've created one stackblitz for your ease. please pitch in.
Upvotes: 0
Views: 2781
Reputation: 407
If you're trying to populate cards in the list, that should be done with .map
on an array. It works similarly to ngFor
from Angular. So, you've got that piece correct. Where things will get different is by setting the width of your columns. You're going to need to be more reliant upon CSS to get the grid set. Styled components are a nice option since they allow you access to prop values. However, you can also work inline if need be.
const StyledCol = styled(Col)`
width: calc(100% / ${colCount}); /* Dynamically sets the grid column widths based on it's parent container element width */
`;
If you need to maintain px value, in the props, you'll need to figure out the width of the container then just divide that by the number of columns.
const pxWidth = containerPxWidth / colCount;
...
width={pxWidth}
I would suggest moving the width and height settings to your <Col>
instead though. Then you can size the image to 100%
(or whatever percentage) of the parent dimensions. This allows for some more flexibility in how you move the children within the given grid space.
Card.js
// Destructuring for the win
const { tiles: localTiles, colCount } = props;
// If you need to have this inline, also need to figure out `containerPxWidth`
// value based on the width of the `Row`
const pxWidth = containerPxWidth / colCount;
return (
<div>
{/* You can auto return map with parenthesis */}
{localTiles.map((tile, index) => (
<div>
<Row height={100}>
<Col md={4} width={pxWidth}>
<p>{tile.text}</p>
<Image
className="tile-image"
src={tile.imageSource}
alt="logo"
/>
</Col>
</Row>
</div>
))}
</div>
);
Upvotes: 1