Part of a collection of Higher-Order Components for React, especially useful with Recompose.
Dynamically map component size and position changes to props using Resize Observer API (Can I use? 🙈).
yarn add @hocs/with-resize-observer-props
withResizeObserverProps(
mapStateToProps: (observerState: Object) => Object
onRefName?: string
): HigherOrderComponent
Where:
observerState
–contentRect
object withwidth
,height
,top
andleft
properties.onRefName
– in some cases you might want to change it.'onRef'
by default.
import React from 'react'
import 'resize-observer-polyfill/dist/ResizeObserver.global'
import { compose, pure } from 'recompose'
import withResizeObserverProps from '@hocs/with-resize-observer-props'
const styles = {
width: 400,
resize: 'both',
overflow: 'hidden',
border: '1px solid #000'
}
const Demo = ({ onRef, hasNarrowWidth, hasLongHeight }) => (
<div ref={onRef} style={styles}>
<h2>resize me!</h2>
{JSON.stringify({ hasNarrowWidth, hasLongHeight })}
</div>
)
export default compose(
withResizeObserverProps(
({ width, height }) => ({
hasNarrowWidth: width < 500,
hasLongHeight: height >= 300
})
),
pure
)(Demo)
- You still might need a polyfill – contains many details on why this particular polyfill is just technically amazing.
- It's impossible to avoid first render with undefined observer state.
- "
ref
approach" is used instead offindDOMNode(this)
because it's just less evil. Also it's more flexible so you can pass it to whatever children you want. - Target Component will be just passed through on unsupported platforms (i.e.
global.ResizeObserver
is not a function) like IE9, JSDOM (so Jest as well) or with Server-Side Rendering. This means that there will be no state (i.e.undefined
) which might be expected, but you can take care of it using RecomposedefaultProps
HOC if it's really necessary.