Created
December 4, 2017 20:15
-
-
Save vincentriemer/25e04d9b81c217b0ec98950eb06bc10c to your computer and use it in GitHub Desktop.
React Component prototype that provides element query functionality via ResizeObserver
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import * as React from "react"; | |
import ResizeObserver from "resize-observer-polyfill"; | |
import invariant from "invariant"; | |
type Entry = { | |
+contentRect: { | |
+width: number, | |
+height: number | |
} | |
}; | |
type ROProps = { | |
children: (width: number, height: number) => React.Node | |
}; | |
type ROState = { | |
width: number, | |
height: number | |
}; | |
export default class ResizeObservable extends React.Component< | |
ROProps, | |
ROState | |
> { | |
ro: ?ResizeObserver; | |
domElement: ?HTMLElement; | |
constructor(props: ROProps) { | |
super(props); | |
this.state = { width: 0, height: 0 }; | |
} | |
componentDidMount() { | |
this.ro = new ResizeObserver(this.handleResize); | |
invariant(this.domElement, `No DOM element has been set by ref to observe`); | |
this.ro.observe(this.domElement); | |
} | |
componentWillUnmount() { | |
if (this.ro != null) { | |
this.ro.disconnect(); | |
this.ro = null; | |
} | |
} | |
handleResize = (entries: $ReadOnlyArray<Entry>) => { | |
const { width, height } = entries[0].contentRect; | |
this.setState({ width, height }); | |
}; | |
handleRef = (elem: ?HTMLElement) => { | |
this.domElement = elem; | |
}; | |
render() { | |
const { children, ...restProps } = this.props; | |
const { width, height } = this.state; | |
return ( | |
<div {...restProps} ref={this.handleRef}> | |
{children(width, height)} | |
</div> | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ResizeObservable className="foo" style={{ flex: 1 }}> // should be able to style the container however you want (I personally use inline styles) | |
{(width) => { | |
if (width <= 300) { | |
return "This is small"; | |
} else { | |
return "This is big"; | |
} | |
}} | |
</ResizeObservable> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment