React Component Size Awareness
react-sizeme is a React library that enables components to be aware of their own rendered width and/or height, facilitating component-level responsive design. The current stable version is 3.0.2, actively maintained with recent updates including React 18 support. It differentiates itself by offering both render prop (`SizeMe`) and Higher-Order Component (`withSize`) patterns, ensuring flexibility for various component structures. It boasts performance, extensive browser support, a tiny bundle size, and compatibility with both functional and class components. The library provides configurable options for monitoring dimensions, refresh rates, and refresh modes (throttle/debounce) to optimize performance.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'width')
cause The `size` prop or `size` object from the render prop might be `undefined` during initial render or Server-Side Rendering (SSR) before the client-side measurement occurs.fixAdd defensive checks for `size` and its properties. For example, `size?.width ?? 'N/A'` or ensure your component handles an `undefined` `size` gracefully, possibly by rendering a placeholder. -
My component is not resizing even when its container changes size.
cause This is often due to `monitorWidth` or `monitorHeight` being set incorrectly or the `refreshRate`/`refreshMode` options preventing frequent updates.fixVerify that `monitorWidth` (default: true) and `monitorHeight` (default: false) are configured as desired. Adjust `refreshRate` (minimum 16ms) and `refreshMode` ('throttle' or 'debounce') to ensure updates are occurring with appropriate frequency.
Warnings
- breaking Version 3.0.1 removed 'position code', which was an experimental feature. If your application relied on `position` properties being passed to your components, this will be a breaking change.
- gotcha By default, `monitorHeight` is set to `false`. Components will only react to width changes unless explicitly configured to monitor height.
- breaking Version 3.0.2 introduced support for React 18 and removed specific peer dependencies for `react` and `react-dom` to simplify dependency management. While backwards compatible with React 17 and earlier (>=0.14.0), it's important to be aware of the shift.
Install
-
npm install react-sizeme -
yarn add react-sizeme -
pnpm add react-sizeme
Imports
- SizeMe
const { SizeMe } = require('react-sizeme');import { SizeMe } from 'react-sizeme'; - withSize
const withSize = require('react-sizeme').withSize;import { withSize } from 'react-sizeme'; - SizeMeOptions
import type { SizeMeOptions } from 'react-sizeme';
Quickstart
import React from 'react';
import { SizeMe, SizeMeOptions } from 'react-sizeme';
interface MyComponentProps {
title: string;
size: { width?: number; height?: number; };
}
// Functional component using HOC
const MyHOCComponent: React.FC<MyComponentProps> = ({ title, size }) => (
<div>
<h2>{title} (HOC)</h2>
<p>Width: {size.width ?? 'N/A'}px</p>
<p>Height: {size.height ?? 'N/A'}px</p>
</div>
);
const SizedMyHOCComponent = withSize()<{ title: string }>(MyHOCComponent);
// Functional component using Render Prop
const MyRenderPropComponent: React.FC = () => {
const sizeMeConfig: SizeMeOptions = {
monitorHeight: true, // Monitor height as well
refreshRate: 50,
refreshMode: 'debounce'
};
return (
<SizeMe monitorHeight refreshRate={50} refreshMode="debounce">
{({ size }) => (
<div>
<h2>My Render Prop Component</h2>
<p>Width: {size.width ?? 'N/A'}px</p>
<p>Height: {size.height ?? 'N/A'}px</p>
{size.width && size.width < 400 && <p>I'm small!</p>}
{size.width && size.width >= 400 && <p>I'm wide!</p>}
</div>
)}
</SizeMe>
);
};
export default function App() {
return (
<>
<h1>react-sizeme Demo</h1>
<div style={{ border: '1px solid #ccc', padding: '10px', marginBottom: '20px', resize: 'horizontal', overflow: 'auto', maxWidth: '100%' }}>
<SizedMyHOCComponent title="Resizable Box 1" />
</div>
<div style={{ border: '1px solid #ccc', padding: '10px', resize: 'both', overflow: 'auto', maxWidth: '100%', height: '200px' }}>
<MyRenderPropComponent />
</div>
</>
);
}