我们正在使用样式化的组件在屏幕上渲染图像。我试图实现的是,图像应该以惰性方式加载,首先加载分辨率较低的图像,然后加载高分辨率的图像。 这就是我想要做的。
const Imagephone = styled.div`
// width: 25.5rem;
// width: 21rem;
width: 23.75rem;
height: 48.230rem;
margin: 0 auto;
background: ${props => props.primary ? "palevioletred" : "white"};
background-image: url(${props => !props.loaded || props.error ?
`https://some url`:
`https://some url2`
}) ;
background-repeat: no-repeat;
background-size: cover;
position: relative;
top: ;`
在我班上,我有这个
super(props);
this.state = {
loaded: false,
error: false
};
}
componentDidMount() {
const img = new Image();
debugger
img.onload = () => {
debugger
this.setState({
loaded: true
});
debugger
};
img.onerror = () => {
this.setState({
error: true
});
};
}```
and in my render i am doing this .
<Imagephone loaded={this.state.loaded} error={this.state.error} />
` 我担心的是,在挂载组件并加载了映像之后,我们需要将加载状态设置为true,但此部分不会执行。 我没有看到img.onload被执行。如果延迟加载图片,我们应该如何实现。
答案 0 :(得分:1)
问题在于您正在创建一个新的Image
实例,并依赖于它的onload
和onerror
方法。但是,您需要使用渲染的img
的元素onLoad
和onError
道具。
const LazyImage = ({ loadingSrc, actualSrc, errorSrc, ...props }) => {
const [isImageLoaded, setImageLoaded] = React.useState(false);
const [hasError, setHasError] = React.useState(false);
const src = React.useMemo(() => {
if (hasError) {
return errorSrc;
}
if (isImageLoaded) {
return actualSrc;
}
return loadingSrc;
}, [hasError, isImageLoaded])
return (
<img
src={src}
onLoad={() => setImageLoaded(true)}
onError={() => setHasError(true)}
{...props}
/>
)
}
const App = () => (
<LazyImage
loadingSrc="https://media3.giphy.com/media/17mNCcKU1mJlrbXodo/giphy.gif"
actualSrc="https://hackernoon.com/hn-images/1*y6C4nSvy2Woe0m7bWEn4BA.png"
errorSrc="https://kuwaitlifestyleblog.files.wordpress.com/2016/07/windows_bug6-100581894-primary-idge.jpg?w=608&h=405"
width={300}
style={{ margin: '0 auto', display: 'block' }}
/>
)
ReactDOM.render(<App />, document.getElementById('root'))
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<div id="root"></div>
编辑:
使用styled-components
:
const StyledImage = styled.div`
background-image: url("${props => props.error ? props.errorSrc : (props.loading ? props.loadingSrc : props.actualSrc)}");
background-position: center center;
background-size: contain;
width: 300px;
height: 200px;
display: block;
margin: 0 auto;
`;
const LazyImage = ({ loadingSrc, actualSrc, errorSrc, ...props }) => {
const [isImageLoaded, setImageLoaded] = React.useState(false);
const [hasError, setHasError] = React.useState(false);
React.useEffect(() => {
const img = new Image();
img.onload = () => setImageLoaded(true);
img.onerror = () => setHasError(true);
img.src = actualSrc;
}, [actualSrc])
return (
<StyledImage
loadingSrc={loadingSrc}
actualSrc={actualSrc}
errorSrc={actualSrc}
loading={!isImageLoaded}
error={hasError}
{...props}
/>
)
}
const App = () => (
<LazyImage
loadingSrc="https://media3.giphy.com/media/17mNCcKU1mJlrbXodo/giphy.gif"
actualSrc="https://hackernoon.com/hn-images/1*y6C4nSvy2Woe0m7bWEn4BA.png"
errorSrc="https://kuwaitlifestyleblog.files.wordpress.com/2016/07/windows_bug6-100581894-primary-idge.jpg?w=608&h=405"
/>
)
ReactDOM.render(<App />, document.getElementById('root'))
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/styled-components/dist/styled-components.min.js"></script>
<div id="root"></div>
答案 1 :(得分:0)
您的图片需要一个src才能加载某些内容:
componentDidMount() {
const img = new Image();
debugger
img.onload = () => {
debugger
this.setState({
loaded: true
});
debugger
};
img.onerror = () => {
this.setState({
error: true
});
};
// This line will fire a request for the image file
img.src = this.props.imgSrc
}
然后
background-image: url(${props => !props.loaded || props.error
? `https://fallback.url`
: props.imgSrc
});