//@flow import React, { Component } from 'react' import type { ElementRef } from 'react' type Props = { src: string, alt: string } type State = { source?: string } export default class LazyImage extends Component<Props, State> { state = {} observer: IntersectionObserver node: HTMLImageElement setRef: ElementRef<'img'> = (node: HTMLImageElement): void => { this.node = node } componentDidMount() { const { updateSourceIfElementIsInView } = this if (typeof IntersectionObserver === 'undefined') { this.setImageSourceFromProps() return } //$FlowFixMe: signature is wrong in flow this.observer = new IntersectionObserver(updateSourceIfElementIsInView) this.observer.observe(this.node) } updateSourceIfElementIsInView = ( entries: Array<IntersectionObserverEntry>, ) => { const [elementEntry] = entries if (elementEntry.isIntersecting) { this.setImageSourceFromProps() this.observer.disconnect() } } setImageSourceFromProps() { const { src: source } = this.props this.setState({ source }) } render() { const { setRef } = this // eslint-disable-next-line no-unused-vars const { src, alt, ...restProps } = this.props const { source } = this.state return <img {...restProps} alt={alt} src={source} ref={setRef} /> } }