Joe*_*ler 39 javascript http-status-code-404 reactjs
我有一个react组件,它是列表中的详细信息视图.
如果图像不存在并且存在404错误,我试图用默认图像替换图像.
我通常会在img标签中使用onerror方法,但这似乎不起作用.
我不知道如何做出反应.
这是我的组件:
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;
Run Code Online (Sandbox Code Playgroud)
Dee*_*lah 81
这对我来说效果最好
<img src={record.picture} onError={(e)=>{e.target.onerror = null; e.target.src="image_path_here"}}/>
Run Code Online (Sandbox Code Playgroud)
小智 13
您可以使用不受控制的组件:
<img src={this.state.img} ref={img => this.img = img} onError={
() => this.img.src = 'img/default.img'
}>
Run Code Online (Sandbox Code Playgroud)
您只需定义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;
Run Code Online (Sandbox Code Playgroud)
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} />
}
Run Code Online (Sandbox Code Playgroud)
@DepH 的回答很好,但如果您的错误源也没有加载,它确实会产生无限循环。这帮助我避免了回调循环:
onError={(e)=>{ if (e.target.src !== "image_path_here")
{ e.target.onerror = null; e.target.src="image_path_here"; } }}
Run Code Online (Sandbox Code Playgroud)
小智 7
e.target.onerror = null
如果错误图片也无法加载jsx
<img
src={imageSrc}
onError={(e) => (e.target.onerror = null, e.target.src = imageErrorSrc)}/>
Run Code Online (Sandbox Code Playgroud)
由于没有完美的答案,因此我发布了我使用的代码段。我正在使用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,
};
Run Code Online (Sandbox Code Playgroud)
小智 5
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
}}
/>
Run Code Online (Sandbox Code Playgroud)
这就是我目前正在使用的。
如果后备图像也失败,Arthur的答案将导致无限回调。
为了避免这种情况,请首先在构造函数中将imageLoadError的状态设置为true:
constructor(props) {
super(props);
this.state = {
imageLoadError: true,
};
}
Run Code Online (Sandbox Code Playgroud)
然后在onError
函数中检查此状态值,以避免无限回调,
该代码将如下所示:-
<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';
}
}}
/>
Run Code Online (Sandbox Code Playgroud)
遇到了类似的问题,我能找到的最佳解决方案是Georgii Oleinikov的答案。(不需要imageLoadError
按照Nitesh Ranjan在他的回答中的建议创建新状态)
onError={(e)=>{ if (e.target.src !== "image_path_here"){
e.target.onerror = null;
e.target.src="image_path_here";}
}
}
Run Code Online (Sandbox Code Playgroud)
e.target.onerror = null
不需要(并且没有真正帮助),因为 if 条件足以防止无限循环(如果备份图像也无法加载)。
所以:
onError={(e)=>{ if (e.target.src !== "image_path_here"){
e.target.src="image_path_here";}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:另一种方法是在返回括号外设置一个标志并检查 if 语句中的标志。代码应如下所示:
render(){
let errorflag=true;
return(
<img alt='' src={imageUrl}
onError={(e)=>{ if (errorflag){ errorflag=false; e.target.src=url; } }} />
);
}
Run Code Online (Sandbox Code Playgroud)
这是使用钩子的答案:
import React, { useState } from 'react'
/**
* Returns an object that can
* be spread onto an img tag
* @param {String} img
* @param {String} fallback
* @returns {Object} { src: String, onError: Func }
*/
function useFallbackImg(img, fallback) {
const [src, setImg] = useState(img)
function onError(e) {
console.log('Missing img', img, e)
// React bails out of hook renders if the state
// is the same as the previous state, otherwise
// fallback erroring out would cause an infinite loop
setImg(fallback)
}
return { src, onError }
}
/**
* Usage <Image src='someUrl' fallback='fallbackUrl' alt='something' />
*/
function Image({src, fallback, ...rest}) {
const imgProps = useFallbackImg(src, fallback)
return <img {...imgProps} {...rest} />
}
Run Code Online (Sandbox Code Playgroud)
如果你是要处理的src
道具变化,可以传递key
的道具src
。
https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#recommendation-fully-uncontrolled-component-with-a-key
<Image key='someUrl' src='someUrl' fallback='fallbackUrl' alt='...' />
Run Code Online (Sandbox Code Playgroud)
使用这样的键可能会失败的唯一极端人为的边缘情况是使用同级组件。我认为如果它们具有相同的键,则只会呈现一个兄弟节点。为了解决这个问题,您可能可以将 Image 包装在<>
Fragment
.
<><Image key={srcProp} ... /></>
<><Image key={srcProp} ... /></>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
43663 次 |
最近记录: |