I have a UserCard
component.
Its the component code:
class UserCard extends React.Component {
constructor(user) {
super(user);
}
render() {
const getInitials = (str) => {
const wordsArr = str.split(" ");
const initialsArr = wordsArr.map((word) => word[0]);
const initialsStr = initialsArr.join(" ");
return initialsStr;
};
const {
id,
firstName,
lastName,
profilePicture,
cardDescription = "Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia rerum libero nobis laboriosam, quisquam iure placeat quae eos velit fuga?",
} = this.props;
const UserCard = (
<li className="userCardWrapper">
<article className="cardContainer" id={id}>
<div className="cardImgWrapper">
<img
className="cardImg"
src={profilePicture}
alt={`${firstName} ${lastName} photo`}
/>
<div className="initials">
{getInitials(`${firstName} ${lastName}`)}
</div>
</div>
<h2 className="cardName">{`${firstName} ${lastName}`}</h2>
<p className="cardDescription">{cardDescription}</p>
</article>
</li>
);
return UserCard;
}
}
In the component code, I have a div
that follows right after the image is rendered:
<div className="initials">
{getInitials(`${firstName} ${lastName}`)}
</div>
I need this div
as a stub in case the image doesn't load.
My task is to remake this logic. This div
should only be returned if the image didn't load. If the image has loaded, the stub div
is not needed. I'm trying to return it with an onError
handler that I hang on img
, but it doesn't work... the whole project crashes.
Question: how to hang on the onError
handler the return of this div
? Is it really possible to create a separate component for this small stub?
CodePudding user response:
What you could do is to use state in your component.
What you'd need to do is the following:
- Introduce a state in which you save the info if loading the image failed
- Render the image or the substitution conditionally depending on the state
- alter the state when one rror of the image-tag triggers
See the code below for an example implementation
class UserCard extends React.Component {
constructor(user) {
super(user);
}
// state component which contains the info if the image-load failed
state = {
loadError: false
}
render() {
const getInitials = (str) => {
const wordsArr = str.split(" ");
const initialsArr = wordsArr.map((word) => word[0]);
const initialsStr = initialsArr.join(" ");
return initialsStr;
};
const {
id,
firstName,
lastName,
profilePicture,
cardDescription = "Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia rerum libero nobis laboriosam, quisquam iure placeat quae eos velit fuga?",
} = this.props;
const UserCard = (
<li className="userCardWrapper">
<article className="cardContainer" id={id}>
<div className="cardImgWrapper">
{
// render the image tag if no error occured
// use img.onError to set this.state.loadError to true if image load fails
// render substitution element if loading the image failed
!this.state.loadError
? <img
className="cardImg"
src={profilePicture}
alt={`${firstName} ${lastName} photo`
one rror={() => setState({loadError: true})}
}
/>
: <div className="initials">
{getInitials(`${firstName} ${lastName}`)}
</div>
}
<div className="initials">
{getInitials(`${firstName} ${lastName}`)}
</div>
</div>
<h2 className="cardName">{`${firstName} ${lastName}`}</h2>
<p className="cardDescription">{cardDescription}</p>
</article>
</li>
);
return UserCard;
}
}