UNPKG

8.8 kBMarkdownView Raw
1# Handle element resizes like it's 2021!
2
3<img src="https://img.shields.io/npm/dm/react-resize-detector?style=flat-square"> <img src="https://badgen.net/bundlephobia/minzip/react-resize-detector?style=flat-square"> <img src="https://badgen.net/bundlephobia/tree-shaking/react-resize-detector?style=flat-square">
4
5#### [Live demo](http://maslianok.github.io/react-resize-detector/)
6
7Nowadays browsers support element resize handling natively using [ResizeObservers](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver). The library uses these observers to help you handle element resizes in React.
8
9🐥 Tiny <a href="https://bundlephobia.com/result?p=react-resize-detector" target="__blank">~3kb</a>
10
11🐼 Written in TypeScript
12
13🦁 Supports Function and Class Components
14
15🐠 Used by <a href="https://github.com/maslianok/react-resize-detector/network/dependents" target="__blank">20k+ repositories</a>
16
17🦄 Generating 35M+ downloads/year
18
19No `window.resize` listeners! No timeouts! No 👑 viruses! :)
20
21<i>TypeScript-lovers notice: starting from v6.0.0 you may safely remove `@types/react-resize-detector` from you deps list.</i>
22
23## Installation
24
25```ssh
26npm i react-resize-detector
27// OR
28yarn add react-resize-detector
29```
30
31and
32
33```jsx
34import ResizeObserver from 'react-resize-detector';
35
36// or, in case you need IE support and ready to load extra kilobytes
37import ResizeObserver from 'react-resize-detector/build/withPolyfill';
38```
39
40## Examples
41
42Starting from v6.0.0 there are 3 recommended ways to work with `resize-detector` library:
43
44#### 1. React hook (new in v6.0.0)
45
46```jsx
47import { useResizeDetector } from 'react-resize-detector';
48
49const CustomComponent = () => {
50 const { width, height, ref } = useResizeDetector();
51 return <div ref={ref}>{`${width}x${height}`}</div>;
52};
53```
54
55<details><summary>With props</summary>
56
57```js
58import { useResizeDetector } from 'react-resize-detector';
59
60const CustomComponent = () => {
61 const { width, height, ref } = useResizeDetector({
62 handleHeight: false,
63 refreshMode: 'debounce',
64 refreshRate: 1000,
65 onResize: (width, height) => {
66 /* Handle resize */
67 }
68 });
69 return <div ref={ref}>{`${width}x${height}`}</div>;
70};
71```
72
73</details>
74
75<details><summary>With custom ref</summary>
76
77```js
78import { useResizeDetector } from 'react-resize-detector';
79
80const CustomComponent = () => {
81 const targetRef = userRef();
82 const { width, height } = useResizeDetector({ targetRef });
83 return <div ref={targetRef}>{`${width}x${height}`}</div>;
84};
85```
86
87</details>
88
89#### 2. HOC pattern
90
91```jsx
92import { withResizeDetector } from 'react-resize-detector';
93
94const CustomComponent = ({ width, height }) => <div>{`${width}x${height}`}</div>;
95
96export default withResizeDetector(CustomComponent);
97```
98
99#### 3. Child Function Pattern
100
101```jsx
102import ReactResizeDetector from 'react-resize-detector';
103
104// ...
105
106<ReactResizeDetector handleWidth handleHeight>
107 {({ width, height }) => <div>{`${width}x${height}`}</div>}
108</ReactResizeDetector>;
109```
110
111<details><summary>Full example (Class Component)</summary>
112
113```jsx
114import React, { Component } from 'react';
115import { withResizeDetector } from 'react-resize-detector';
116
117const containerStyles = {
118 height: '100vh',
119 display: 'flex',
120 alignItems: 'center',
121 justifyContent: 'center'
122};
123
124class AdaptiveComponent extends Component {
125 state = {
126 color: 'red'
127 };
128
129 componentDidUpdate(prevProps) {
130 const { width } = this.props;
131
132 if (width !== prevProps.width) {
133 this.setState({
134 color: width > 500 ? 'coral' : 'aqua'
135 });
136 }
137 }
138
139 render() {
140 const { width, height } = this.props;
141 const { color } = this.state;
142 return <div style={{ backgroundColor: color, ...containerStyles }}>{`${width}x${height}`}</div>;
143 }
144}
145
146const AdaptiveWithDetector = withResizeDetector(AdaptiveComponent);
147
148const App = () => {
149 return (
150 <div>
151 <p>The rectangle changes color based on its width</p>
152 <AdaptiveWithDetector />
153 </div>
154 );
155};
156
157export default App;
158```
159
160</details>
161
162<details><summary>Full example (Functional Component)</summary>
163
164```jsx
165import React, { useState, useEffect } from 'react';
166import { withResizeDetector } from 'react-resize-detector';
167
168const containerStyles = {
169 height: '100vh',
170 display: 'flex',
171 alignItems: 'center',
172 justifyContent: 'center'
173};
174
175const AdaptiveComponent = ({ width, height }) => {
176 const [color, setColor] = useState('red');
177
178 useEffect(() => {
179 setColor(width > 500 ? 'coral' : 'aqua');
180 }, [width]);
181
182 return <div style={{ backgroundColor: color, ...containerStyles }}>{`${width}x${height}`}</div>;
183};
184
185const AdaptiveWithDetector = withResizeDetector(AdaptiveComponent);
186
187const App = () => {
188 return (
189 <div>
190 <p>The rectangle changes color based on its width</p>
191 <AdaptiveWithDetector />
192 </div>
193 );
194};
195
196export default App;
197```
198
199</details>
200
201<br/>
202
203We 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.
204
205## Refs
206
207The 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.
208
209For 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`
210
211<details><summary>HOC pattern example</summary>
212
213```jsx
214import { withResizeDetector } from 'react-resize-detector';
215
216const CustomComponent = ({ width, height, targetRef }) => <div ref={targetRef}>{`${width}x${height}`}</div>;
217
218export default withResizeDetector(CustomComponent);
219```
220
221</details>
222
223<details><summary>Child Function Pattern example</summary>
224
225```jsx
226import ReactResizeDetector from 'react-resize-detector';
227
228// ...
229
230<ReactResizeDetector handleWidth handleHeight>
231 {({ width, height, targetRef }) => <div ref={targetRef}>{`${width}x${height}`}</div>}
232</ReactResizeDetector>;
233```
234
235</details>
236
237## API
238
239| Prop | Type | Description | Default |
240| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
241| onResize | Func | Function that will be invoked with `width` and `height` arguments | `undefined` |
242| handleWidth | Bool | Trigger `onResize` on width change | `true` |
243| handleHeight | Bool | Trigger `onResize` on height change | `true` |
244| skipOnMount | Bool | Do not trigger onResize when a component mounts | `false` |
245| 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` |
246| refreshRate | Number | Use this in conjunction with `refreshMode`. Important! It's a numeric prop so set it accordingly, e.g. `refreshRate={500}` | `1000` |
247| 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` |
248| 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` |
249
250## License
251
252MIT
253
254## ❤️
255
256Show us some love and STAR ⭐ the project if you find it useful