Reputation: 11
I'm trying to do some styling with react. I've got a results page, and I want my results cards to stretch (a bit) to fill each line. To do that I'm using...
let body = {
display: "flex",
margin: "0% 10%",
flexWrap: "wrap",
};
and...
let card = {
fontSize: "90%",
flexBasis: "15rem",
minWidth: "10rem",
flexShrink: "1",
flexGrow: "1",
}
My issue is that I also want all the results cards to be the same size. Normally, I'd think about using jQuery for this, but I'm using React and that's a bit awkward.
So, what I'm trying to do is pass the width information of the first results card (child component) back to the results page (parent component) with a callback function. Then, I intend to pass a "maxWidth" property to the other results cards using props. Note: this works, in the sense that I can pass width information back to the parent and I can style a results card using props.
The problem is that when I try to assign the width information to the props of one of the other results cards, it is undefined. I suspect this is because you can't update the state and take information from the state while a JSX element is rendering...
Any ideas about how I can achieve what I want? Any ideas about how I can somehow pause the render in order to update the state?
All the best
Parent Component
import React from 'react';
import ReactDOM from 'react-dom';
import Card from './Card.js';
class Body extends React.Component {
constructor(props){
super(props);
this.state = {
};
this.cardWidth = function (width) {
this.state.cardWidth = width;
console.log(this.state.cardWidth);
}.bind(this);
};
render() {
return (
<div className="body" style={body}>
<Card cardWidth={this.cardWidth}/>
<Card style={{maxWidth:`${this.state.cardWidth}`}}/>
<Card style={{maxWidth:`${this.state.cardWidth}`}}/>
</div>
);
};
};
let body = {
display: "flex",
margin: "0% 10%",
flexWrap: "wrap",
};
export default Body;
Child Component
import React from 'react';
import ReactDOM from 'react-dom';
class Card extends React.Component {
constructor(props){
super(props);
this.state = {
};
this.cardref = React.createRef();
};
componentDidMount() {
if (this.props.cardWidth) {
this.props.cardWidth(this.cardref.current.offsetWidth);
};
};
render() {
return (
<div className="card" style={(this.props.style)?(Object.assign({}, this.props.style, card)): card} ref={this.cardref}>
<div className="card-body">
<h5 className="card-title" style={{fontSize: "100%"}}>Card title</h5>
<p className="card-text" style={pText}>Some quick example text to build on the card title and make up the bulk of the card's content.</p>
<a href="#" className="btn btn-primary" style={{fontSize: "80%"}}>Go somewhere</a>
</div>
</div>
);
};
};
let card = {
fontSize: "90%",
flexBasis: "15rem",
minWidth: "10rem",
// maxWidth: "15rem",
flexShrink: "1",
flexGrow: "1",
}
let pText = {
display: "block",
textOverflow: "ellipsis",
overflow: "hidden",
height: "4rem",
fontSize: "80%"
};
export default Card;
Upvotes: 0
Views: 3253
Reputation: 11
Turns out I'd missed out px after the maxWidth property value. Now I have the problem that I need it to re-render on a view port resize event.
Upvotes: 1
Reputation: 185
To make all the cards the same size, within a given space, can use flex-grow
. For example if you set flex-grow: 1
on all your cards then they will all grow to fill the extra space evenly. There is a nice diagram on this page also if you look for the 'flex-grow' heading.
Upvotes: 0