react.js Replace img src onerror

后端 未结 22 2963
北恋
北恋 2020-11-29 00:20

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 er

相关标签:
22条回答
  • 2020-11-29 01:15

    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,
    };

    0 讨论(0)
  • 2020-11-29 01:16
    import OriginalImage from '../../originalImg.png'
    import ReplacementImage from '../../replaceImg.png'
    
    <img
     src= OriginalImage
     alt="example"
     onError={(e) => {
        e.target.src = ReplacementImage //replacement image imported above
        e.target.style = 'padding: 8px; margin: 16px' // inline styles in html format
     }}
    />
    

    this is what I'm currently using.

    0 讨论(0)
  • 2020-11-29 01:17

    Its So Simple

    e.target.onerror = null If Error Image Also Fails to Load jsx

    <img 
       src={imageSrc}
       onError={(e) => (e.target.onerror = null, e.target.src = imageErrorSrc)}/>
    
    0 讨论(0)
  • 2020-11-29 01:19

    Arthur's answer will result in infinite callbacks if fallback image also fails.

    To avoid that, first set a state in the constructor for imageLoadError as true :

    constructor(props) {
        super(props);
        this.state = {
          imageLoadError: true,
        };
    }
    

    and then check for this state value in onError function to avoid infinite callbacks,

    the code will look like this :-

    <img
        src={"https://if_this_url_fails_go_to_onError"}
        onError={e => { 
            if(this.state.imageLoadError) { 
                this.setState({
                    imageLoadError: false
                });
                e.target.src = 'fallbackImage.png';
            }
        }}
    />
    
    0 讨论(0)
  • 2020-11-29 01:25

    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; } }} />
                );
    } 
    
    0 讨论(0)
  • 2020-11-29 01:25

    As it was mentioned in one of the comments, the best solution is to use react-image library. Using onError will fail when you try to serve static version of your react website after build.

    Here is super simple and straightforward example how to use react-image, just import Img component

    import {Img} from 'react-image'
    

    And later specify a list of src that you try to load

    <Img
       src={['images/image1.svg', 'images/default.svg']}
       alt="Some title"
    />   
    

    If 1st url not found, the 2nd will be loaded, there are also some other pretty cool features like showing a spinner while image is loading or displaying some other component in case none of the listed images are available

    0 讨论(0)
提交回复
热议问题