I want to load a different image(fake avatar) while the final avatar image is loading. The idea is to detect when the prop image is loaded and change a state. Is it possible? Some ideas? Thank you!
class ImageUser extends React.Component {
constructor(props) {
super(props);
this.state = {userImageLoaded: false};
let imageSrc = "";
if (!this.props.userImage) {
imageSrc = this.props.noUserImage;
} else {
imageSrc = this.props.userImage;
}
this.loadingImage = <img className={styles.imageUser}
src={this.props.loadingImage} alt="2"/>;
this.userImage =
<img onLoad={this.setState({userImageLoaded: true})}
className={styles.imageUser} src={imageSrc}
alt="1"/>;
}
render() {
let image = "";
if (this.state.userImageLoaded) {
image = this.userImage;
} else {
image = this.loadingImage;
}
return (
<div>
{image}
</div>
);
}
}
export default ImageUser;
forEach((image) => { image. addEventListener("load", () => updateStatus(imagesLoaded), { once: true }); image. addEventListener("error", () => updateStatus(imagesLoaded), { once: true }); }); return; }, [ref]); return status; };
Render is always called when state or props change. componentWillReceiveProps used to be the way you could do something with the props before the render occurred.
We used the useEffect hook to update the state of a component when its props change. Copied! The logic in the useEffect hook is reran every time one of its dependencies changes. Every time the parentCount prop changes, the useEffect hook is reran and we use the setChildCount function to update the state.
There are several ways to do this, but the simplest is to display the final image hidden, and then flip it to visible once it loads.
class Foo extends React.Component {
constructor(){
super();
this.state = {loaded: false};
}
render(){
return (
<div>
{this.state.loaded ? null :
<div
style={{
background: 'red',
height: '400px',
width: '400px',
}}
/>
}
<img
style={this.state.loaded ? {} : {display: 'none'}}
src={this.props.src}
onLoad={() => this.setState({loaded: true})}
/>
</div>
);
}
}
Same answer as Brigand's accepted answer but with Hooks:
const Foo = ({ src }) => {
const [loaded, setLoaded] = useState(false);
return (
<div>
{loaded ? null : (
<div
style={{
background: 'red',
height: '400px',
width: '400px'
}}
/>
)}
<img
style={loaded ? {} : { display: 'none' }}
src={src}
onLoad={() => setLoaded(true)}
/>
</div>
);
};
Same idea using reference to the element but using functional component and hooks with typescript:
import React from 'react';
export const Thumbnail = () => {
const imgEl = React.useRef<HTMLImageElement>(null);
const [loaded, setLoaded] = React.useState(false);
const onImageLoaded = () => setLoaded(true);
React.useEffect(() => {
const imgElCurrent = imgEl.current;
if (imgElCurrent) {
imgElCurrent.addEventListener('load', onImageLoaded);
return () => imgElCurrent.removeEventListener('load', onImageLoaded);
}
}, [imgEl]);
return (
<>
<p style={!loaded ? { display: 'block' } : { display: 'none' }}>
Loading...
</p>
<img
ref={imgEl}
src="https://via.placeholder.com/60"
alt="a placeholder"
style={loaded ? { display: 'inline-block' } : { display: 'none' }}
/>
</>
);
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With