Skip to content

Instantly share code, notes, and snippets.

@kpuputti
Created September 5, 2017 11:56
Show Gist options
  • Save kpuputti/1f7b8b572877e3493d264ce333ca73a3 to your computer and use it in GitHub Desktop.
Save kpuputti/1f7b8b572877e3493d264ce333ca73a3 to your computer and use it in GitHub Desktop.
/**
* A higher order component (HOC) that provides the current viewport
* dimensions to the wrapped component as a `viewport` prop that has
* the shape `{ width: 600, height: 400}`.
*/
export const withViewport = Component => {
// The resize event is flooded when the browser is resized. We'll
// use a small timeout to throttle changing the viewport since it
// will trigger rerendering.
const WAIT_MS = 100;
class WithViewportComponent extends ReactComponent {
constructor(props) {
super(props);
this.state = { width: 0, height: 0 };
this.handleWindowResize = this.handleWindowResize.bind(this);
this.setViewport = throttle(this.setViewport.bind(this), WAIT_MS);
}
componentDidMount() {
this.setViewport();
window.addEventListener('resize', this.handleWindowResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleWindowResize);
}
handleWindowResize() {
this.setViewport();
}
setViewport() {
this.setState({
width: window.innerWidth,
height: window.innerHeight,
});
}
render() {
const viewport = this.state;
const props = { ...this.props, viewport };
return <Component {...props} />;
}
}
WithViewportComponent.displayName = `withViewport(${Component.displayName || Component.name})`;
return WithViewportComponent;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment