I have a react component that is the detail view from a list.
I am trying to replace the image with a default image if the image does not exist and there is a 404 error.
I would normally use the onerror method in the img tag but that doesn’t seem to be working.
I am not sure how to do this with react.
Here is my component:
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); } render() { return ( <div className='container'> <div className='list-group'> <div className='list-group-item animated fadeIn'> <h4>{this.state.contact.displayname}</h4> <img src={this.state.imageUrl} /> </div> </div> </div> ); } } export default Contact;
Advertisement
Answer
Since there is no perfect answer, I am posting the snippet I use. I am using reusable Image
component that falls back 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, };