react.js 替换 img src onerror

IT技术 javascript reactjs http-status-code-404
2021-02-27 04:49:03

我有一个react组件,它是列表中的详细视图。

如果图像不存在并且出现 404 错误,我会尝试用默认图像替换图像。

我通常会在 img 标签中使用 onerror 方法,但这似乎不起作用。

我不知道如何通过react来做到这一点。

这是我的组件:

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;
6个回答

这对我最有效

<img src={record.picture} onError={(e)=>{e.target.onerror = null; e.target.src="image_path_here"}}/>
@tomhughes 当“image_path_here”失败时,它会阻止无限回调
2021-04-18 04:49:03
如果“image_path_here”产生并出错,这种方法似乎会导致无限回调......
2021-04-29 04:49:03
我收到错误: Property 'onError' does not exist on type 'EventTarget'
2021-04-30 04:49:03
谢谢你的回答。它真的很有帮助。
2021-05-03 04:49:03
@DeepakMallah 我按照你的代码<img src={imageUrl} className={cs.image} onError={(e) => {e.target.src = 'https://upload.wikimedia.org/wikipedia/en/c/c3/The_Martian_2014.jpg'; e.target.onError = null;}} />但是,Safari 中的控制台仍然显示错误Failed to load resource: the server responded with a status of 404 (Not Found)正常吗?如何消除这个控制台错误?谢谢。
2021-05-12 04:49:03

由于没有完美的答案,我发布了我使用的代码段。我正在使用Image回退到fallbackSrc.

由于后备图像可能会再次失败并触发重新渲染的无限循环,因此我添加了errored状态。

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

我使用 TypeScript 扩展了这个答案并添加了占位符支持stackoverflow.com/a/68378797/3457769
2021-05-05 04:49:03
一点注意:如果您将 React 与服务器端渲染一起使用,则不起作用,因为图像是异步加载的,并且在进行水合时,所有错误都已经被触发。
2021-05-10 04:49:03

您可以使用不受控制的组件:

<img src={this.state.img} ref={img => this.img = img} onError={
    () => this.img.src = 'img/default.img'
}>
谢谢,它对我有用!为什么不是公认的答案?
2021-04-28 04:49:03

2021 使用 React Functional Components、Hooks 和 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} />
}


我也希望你得到更多的赞成,这个答案太低了。
2021-04-21 04:49:03
您不需要跟踪错误,仅在状态更改时重新渲染。将值设置为fallbacktofallback不会导致重新渲染,const onError = () => setImgSrc(fallback);很好..
2021-05-06 04:49:03

您只需要定义 onError 处理程序而不是更改将触发组件渲染方法的状态,最终组件将使用占位符重新渲染。

请不要同时使用 jQuery 和 React!

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;
@GuilhermeNunes React Bootstrap没有!
2021-04-28 04:49:03
但是引导程序需要 Jquery 兄弟
2021-05-12 04:49:03