react.js Replace img src onerror

2020-01-27 15:02发布

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;

16条回答
等我变得足够好
2楼-- · 2020-01-27 15:28

I wrote like this.

import React, { useState } from 'react';
import NoImageSVG from './noImage.svg';

const ImgWithFallback: React.FunctionComponent<{ src: string; alt: string; className: string }> = ({
  src,
  alt,
  className,
}) => {
  const [isUndefined, updateIsUndefined] = useState(false);

  const onError = () => {
    updateIsUndefined(true);
  };

  if (isUndefined) {
    return (
      <div className={className}>
        <NoImageSVG width='5rem' height='5rem' />
      </div>
    );
  }

  return <img src={src} alt={alt} className={className} onError={onError} />;
};

export default React.memo(ImgWithFallback, () => true);

查看更多
我只想做你的唯一
3楼-- · 2020-01-27 15:29

This works best for me

<img src={record.picture} onError={(e)=>{e.target.onerror = null; e.target.src="image_path_here"}}/>
查看更多
Rolldiameter
4楼-- · 2020-01-27 15:31

Ran into a similar problem and the best solution i could find was Georgii Oleinikov's answer. (Doesn't require making new imageLoadError state as suggested by Nitesh Ranjan in his answer)

onError={(e)=>{ if (e.target.src !== "image_path_here"){
                    e.target.onerror = null;
                     e.target.src="image_path_here";}
                }
           }

e.target.onerror = null is not needed (and doesn't really help) because the if condition is enough to prevent the infinite loop(if backup image fails to load as well).

So:

onError={(e)=>{ if (e.target.src !== "image_path_here"){
                 e.target.src="image_path_here";}
               }
         }

EDIT: The other way around is to set a flag outside the return brackets and check for the flag in the if statement. Code should look something like this:

render(){
 let errorflag=true;
 return(
            <img alt='' src={imageUrl} 
                    onError={(e)=>{ if (errorflag){ errorflag=false; e.target.src=url; } }} />
            );
} 
查看更多
趁早两清
5楼-- · 2020-01-27 15:31

That's how I did it.

 class Pix extends React.Component{

          constructor(props){
            super(props);
           this.state={link: this.props.link};
           this.onError=this.onError.bind(this);
          }


          onError(){
              console.log("error: could not find picture");
              this.setState(function(){ return {link: "missing.png"}; });
             };

          render(){
          return <img onError={this.onError} src={this.state.link}/>;
          } 
    }
查看更多
走好不送
6楼-- · 2020-01-27 15:32

If anyone is using image src with require then onError doesn't work as -

<img src={require(`./../../assets/images/${props.imgName}.png`)} className="card-img" alt={props.name} />

then require throws an error, where I tried multiple ways and came to try and catch block solution as -

  let imgSrc;
  try {
    imgSrc = require(`./../../assets/images/${props.imgName}.png`);  
  } catch {
    imgSrc = require(`./../../assets/images/default.png`);
  }

and use as

<img src={imgSrc} className="card-img" alt={props.name} />
查看更多
甜甜的少女心
7楼-- · 2020-01-27 15:33

You can use uncontrolled component:

<img src={this.state.img} ref={img => this.img = img} onError={
    () => this.img.src = 'img/default.img'
}>
查看更多
登录 后发表回答