UNPKG

7.04 kBMarkdownView Raw
1# Handle element resizes like it's 2020!
2
3<img src="https://img.shields.io/npm/dy/react-resize-detector?style=flat-square">
4<img src="https://img.shields.io/npm/dm/react-resize-detector?style=flat-square">
5
6#### [Live demo](http://maslianok.github.io/react-resize-detector/)
7
8Nowadays browsers have started to support element resize handling natively using [ResizeObservers](https://wicg.github.io/ResizeObserver/). We use this feature (with a [polyfill](https://github.com/que-etc/resize-observer-polyfill)) to help you handle element resizes in React.
9No `window.resize` listeners! No timeouts! Just a pure implementation with a lightning-fast polyfill!
10
11## Installation
12
13```
14npm i react-resize-detector
15// OR
16yarn add react-resize-detector
17```
18
19## Examples
20
21Starting from v5.0.0 there are 2 recommended ways to work with `resize-detector` library:
22
23#### 1. HOC pattern
24
25```jsx
26import { withResizeDetector } from 'react-resize-detector';
27
28const CustomComponent = ({ width, height }) => <div>{`${width}x${height}`}</div>;
29
30export default withResizeDetector(CustomComponent);
31```
32
33#### 2. Child Function Pattern
34
35```jsx
36import ReactResizeDetector from 'react-resize-detector';
37
38// ...
39
40<ReactResizeDetector handleWidth handleHeight>
41 {({ width, height }) => <div>{`${width}x${height}`}</div>}
42</ReactResizeDetector>;
43```
44
45<details><summary>Full example (Class Component)</summary>
46
47```jsx
48import React, { Component } from 'react';
49import { withResizeDetector } from 'react-resize-detector';
50
51const containerStyles = {
52 height: '100vh',
53 display: 'flex',
54 alignItems: 'center',
55 justifyContent: 'center'
56};
57
58class AdaptiveComponent extends Component {
59 state = {
60 color: 'red'
61 };
62
63 componentDidUpdate(prevProps) {
64 const { width } = this.props;
65
66 if (width !== prevProps.width) {
67 this.setState({
68 color: width > 500 ? 'coral' : 'aqua'
69 });
70 }
71 }
72
73 render() {
74 const { width, height } = this.props;
75 const { color } = this.state;
76 return <div style={{ backgroundColor: color, ...containerStyles }}>{`${width}x${height}`}</div>;
77 }
78}
79
80const AdaptiveWithDetector = withResizeDetector(AdaptiveComponent);
81
82const App = () => {
83 return (
84 <div>
85 <p>The rectangle changes color based on its width</p>
86 <AdaptiveWithDetector />
87 </div>
88 );
89};
90
91export default App;
92```
93
94</details>
95
96<details><summary>Full example (Functional Component)</summary>
97
98```jsx
99import React, { useState, useEffect } from 'react';
100import { withResizeDetector } from 'react-resize-detector';
101
102const containerStyles = {
103 height: '100vh',
104 display: 'flex',
105 alignItems: 'center',
106 justifyContent: 'center'
107};
108
109const AdaptiveComponent = ({ width, height }) => {
110 const [color, setColor] = useState('red');
111
112 useEffect(() => {
113 setColor(width > 500 ? 'coral' : 'aqua');
114 }, [width]);
115
116 return <div style={{ backgroundColor: color, ...containerStyles }}>{`${width}x${height}`}</div>;
117};
118
119const AdaptiveWithDetector = withResizeDetector(AdaptiveComponent);
120
121const App = () => {
122 return (
123 <div>
124 <p>The rectangle changes color based on its width</p>
125 <AdaptiveWithDetector />
126 </div>
127 );
128};
129
130export default App;
131```
132
133</details>
134
135<br/>
136
137We still support [other ways](https://github.com/maslianok/react-resize-detector/tree/v4.2.1#examples) to work with this library, but in the future consider using the ones described above. Please let me know if the examples above don't fit your needs.
138
139## Refs
140
141The library is trying to be smart and to not add any extra DOM elements to not break your layouts. That's why we use [`findDOMNode`](https://reactjs.org/docs/react-dom.html#finddomnode) method to find and attach listeners to the existing DOM elements. Unfortunately, this method has been deprecated and throws a warning in StrictMode.
142
143For those who wants to avoid this warning we are introducing an additional property `targetRef`. You have to set this prop as a `ref` of your target DOM element and the library will use this reference instead of serching the DOM element with help of `findDOMNode`
144
145<details><summary>HOC pattern example</summary>
146
147```jsx
148import { withResizeDetector } from 'react-resize-detector';
149
150const CustomComponent = ({ width, height, targetRef }) => <div ref={targetRef}>{`${width}x${height}`}</div>;
151
152export default withResizeDetector(CustomComponent);
153```
154
155</details>
156
157<details><summary>Child Function Pattern example</summary>
158
159```jsx
160import ReactResizeDetector from 'react-resize-detector';
161
162// ...
163
164<ReactResizeDetector handleWidth handleHeight>
165 {({ width, height, targetRef }) => <div ref={targetRef}>{`${width}x${height}`}</div>}
166</ReactResizeDetector>;
167```
168
169</details>
170
171## API
172
173| Prop | Type | Description | Default |
174| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
175| onResize | Func | Function that will be invoked with `width` and `height` arguments | `undefined` |
176| handleWidth | Bool | Trigger `onResize` on width change | `true` |
177| handleHeight | Bool | Trigger `onResize` on height change | `true` |
178| skipOnMount | Bool | Do not trigger onResize when a component mounts | `false` |
179| refreshMode | String | Possible values: `throttle` and `debounce` See [lodash docs](https://lodash.com/docs#debounce) for more information. `undefined` - callback will be fired for every frame | `undefined` |
180| refreshRate | Number | Use this in conjunction with `refreshMode`. Important! It's a numeric prop so set it accordingly, e.g. `refreshRate={500}` | `1000` |
181| refreshOptions | Object | Use this in conjunction with `refreshMode`. An object in shape of `{ leading: bool, trailing: bool }`. Please refer to [lodash's docs](https://lodash.com/docs/4.17.11#throttle) for more info | `undefined` |
182| targetRef | Ref | Use this prop to pass a reference to the element you want to attach resize handlers to. It must be an instance of `React.useRef` or `React.createRef` functions | `undefined` |
183
184## License
185
186MIT