Skip to content

Instantly share code, notes, and snippets.

@undrafted
Last active January 27, 2021 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save undrafted/a3871839c9905150048ce4d44ffc669d to your computer and use it in GitHub Desktop.
Save undrafted/a3871839c9905150048ce4d44ffc669d to your computer and use it in GitHub Desktop.
import React, { PureComponent, ReactNode } from 'react';
const isBrowser = () => typeof window !== 'undefined' && typeof document !== 'undefined';
const shouldPolyfillIntersectionObserver = () =>
isBrowser() &&
!(
'IntersectionObserver' in window &&
'IntersectionObserverEntry' in window &&
'intersectionRatio' in IntersectionObserverEntry.prototype
);
if (shouldPolyfillIntersectionObserver()) {
require('intersection-observer');
}
type WithIntersectionObserverProps = {
shouldLoadAsset: boolean;
children?: ReactNode;
};
type WithIntersectionObserverState = {
shouldLoadAsset: boolean;
};
const getDisplayName = (Component: React.ComponentType): string =>
Component.displayName || Component.name || 'Component';
export const withIntersectionObserver = (options: IntersectionObserverInit) => (
Component: React.ComponentType<WithIntersectionObserverProps>,
) => {
return class extends PureComponent<{}, WithIntersectionObserverState> {
observer: IntersectionObserver;
element: HTMLElement;
state: WithIntersectionObserverState = {
shouldLoadAsset: false,
};
intersectionCallback = (entries: IntersectionObserverEntry[]) => {
entries.forEach((entry: IntersectionObserverEntry) => {
const { isIntersecting } = entry;
if (isIntersecting) {
this.setState({ shouldLoadAsset: true });
this.observer.disconnect();
}
});
};
componentDidMount() {
this.observer = new IntersectionObserver(this.intersectionCallback, options);
this.observer.observe(this.element);
}
render() {
return (
<div ref={el => (this.element = el)}>
{React.createElement(Component, { ...this.props, ...this.state })}
</div>
);
}
static displayName = `WithItersectionObserver(${getDisplayName(Component)})`;
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment