Skip to content

Instantly share code, notes, and snippets.

@mrnkr
Created February 3, 2019 22:34
Show Gist options
  • Save mrnkr/01e2ff54afd1a19734d414107073facf to your computer and use it in GitHub Desktop.
Save mrnkr/01e2ff54afd1a19734d414107073facf to your computer and use it in GitHub Desktop.
React component which renders a blurred preview of an image until it enters the viewport (uses intersection observer)
import React, { Component, CSSProperties } from 'react';
export interface Props {
'className'?: string;
'style'?: CSSProperties;
'src': string;
'data-src': string;
[key: string]: any;
}
export interface State {
intersecting: boolean;
}
export default class LazyImage extends Component<Props, State> {
public state: State = {
intersecting: false
}
private img: React.RefObject<HTMLImageElement> = React.createRef();
private intersection = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (!entry.isIntersecting)
return;
this.setState({ intersecting: true });
this.intersection.unobserve(entry.target);
})
})
public componentDidMount() {
const { img, intersection } = this;
if (!img.current)
throw new Error('Somehow img is not defined 😒');
intersection.observe(img.current);
}
public componentWillUnmount() {
this.intersection.disconnect();
}
public render() {
const { className: c, src, ['data-src']: dataSrc, ...props } = this.props;
const { intersecting } = this.state;
return intersecting ? (
<img className={c} src={dataSrc} {...props} />
) : (
<img ref={this.img} className={`${c} lazy`} src={src} {...props} />
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment