react.js Replace img src onerror
Solution 1:
This works best for me
<img
src={record.picture}
onError={({ currentTarget }) => {
currentTarget.onerror = null; // prevents looping
currentTarget.src="image_path_here";
}}
/>
Solution 2:
Since there is no perfect answer, I am posting the snippet I use. I am using reusable Image
component that fallbacks to fallbackSrc
.
Since the fallback image could fail again and trigger infinite loop of re-rendering, I added errored
state.
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Image extends Component {
constructor(props) {
super(props);
this.state = {
src: props.src,
errored: false,
};
}
onError = () => {
if (!this.state.errored) {
this.setState({
src: this.props.fallbackSrc,
errored: true,
});
}
}
render() {
const { src } = this.state;
const {
src: _1,
fallbackSrc: _2,
...props
} = this.props;
return (
<img
src={src}
onError={this.onError}
{...props}
/>
);
}
}
Image.propTypes = {
src: PropTypes.string,
fallbackSrc: PropTypes.string,
};
Solution 3:
You can use uncontrolled component:
<img src={this.state.img} ref={img => this.img = img} onError={
() => this.img.src = 'img/default.img'
}>
Solution 4:
2021 Updated Answer using React Functional Components, Hooks and TypeScript
// ImageWithFallback.tsx
import React, { ImgHTMLAttributes, useState } from 'react'
interface Props extends ImgHTMLAttributes<any> {
fallback: string
}
export default function ImageWithFallback({ fallback, src, ...props }: Props) {
const [imgSrc, setImgSrc] = useState<string | undefined>(src)
const onError = () => setImgSrc(fallback)
return <img src={imgSrc ? imgSrc : fallback} onError={onError} {...props} />
}
Solution 5:
You need just define onError handler than change the state which will trigger component render method and eventually component will re-render with placeholder.
Please, don't use jQuery and React together!
import React from 'react';
import {Link} from 'react-router';
import ContactStore from '../stores/ContactStore'
import ContactActions from '../actions/ContactActions';
class Contact extends React.Component {
constructor(props) {
super(props);
this.state = ContactStore.getState();
this.onChange = this.onChange.bind(this);
}
componentDidMount() {
ContactStore.listen(this.onChange);
ContactActions.getContact(this.props.params.id);
}
componentWillUnmount() {
ContactStore.unlisten(this.onChange);
}
componentDidUpdate(prevProps) {
if (prevProps.params.id !== this.props.params.id) {
ContactActions.getContact(this.props.params.id);
}
}
onChange(state) {
this.setState(state);
}
onError() {
this.setState({
imageUrl: "img/default.png"
})
}
render() {
return (
<div className='container'>
<div className='list-group'>
<div className='list-group-item animated fadeIn'>
<h4>{this.state.contact.displayname}</h4>
<img onError={this.onError.bind(this)} src={this.state.imageUrl} />
</div>
</div>
</div>
);
}
export default Contact;