Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

😎 📏 React hook to measure an element's size and handle responsive components.

License

NotificationsYou must be signed in to change notification settings

wellyshen/react-cool-dimensions

A Reacthook that measure an element's size and handleresponsive components with highly-performant way, usingResizeObserver. Try it you will 👍🏻 it!

❤️ it? ⭐️ it onGitHub orTweet about it.

build statuscoverage statusnpm versionnpm downloadsnpm downloadsgzip sizeAll ContributorsPRs welcomeTwitter URL

demo

⚡️ Try yourself:https://react-cool-dimensions.netlify.app

Features

Requirement

To usereact-cool-dimensions, you must usereact@16.8.0 or greater which includes hooks.

Installation

This package is distributed vianpm.

$ yarn add react-cool-dimensions# or$ npm install --save react-cool-dimensions

Usage

react-cool-dimensions has a flexibleAPI design, it can cover simple to complex use cases for you. Here are some examples to show you how does it work.

⚠️Most modern browsers support ResizeObserver natively. You can also usepolyfill for full browser support.

Basic Use Case

To report the size of an element by thewidth andheight states.

importuseDimensionsfrom"react-cool-dimensions";constApp=()=>{const{ observe, unobserve, width, height, entry}=useDimensions({onResize:({ observe, unobserve, width, height, entry})=>{// Triggered whenever the size of the target is changed...unobserve();// To stop observing the current target elementobserve();// To re-start observing the current target element},});return(<divref={observe}>      Hi! My width is{width}px and height is{height}px</div>);};

💡 You don't have to callunobserve when the component is unmounted, this hook will handle it for you.

Responsive Components

We havemedia queries but those are based on the browser viewport not individual elements. In some cases, we'd like to style components based on the width of a containing element rather than the browser viewport. To meet this demand there's aproposal forcontainer queries, but it still doesn't exist today...

No worries,react-cool-dimensions provides an alternative solution for us! We can activate theresponsive mode by thebreakpoints option. It's a width-based solution, once it's activated we can easily apply different styles to a component according to thecurrentBreakpoint state. The overall concept as below.

If you wish to update the state on the breakpoints changed, you can set theupdateOnBreakpointChange option totrue.

importuseDimensionsfrom"react-cool-dimensions";constCard=()=>{const{ observe, currentBreakpoint}=useDimensions({// The "currentBreakpoint" will be the object key based on the target's width// for instance, 0px - 319px (currentBreakpoint = XS), 320px - 479px (currentBreakpoint = SM) and so onbreakpoints:{XS:0,SM:320,MD:480,LG:640},// Will only update the state on breakpoint changed, default is falseupdateOnBreakpointChange:true,onResize:({ currentBreakpoint})=>{// Now the event callback will be triggered when breakpoint is changed// we can also access the "currentBreakpoint" here},});return(<divclass={`card${currentBreakpoint}`}ref={observe}><divclass="card-header">I'm 😎</div><divclass="card-body">I'm 👕</div><divclass="card-footer">I'm 👟</div></div>);};

Note: If thebreakpoints option isn't set or there's no the defined breakpoint (object key) for a range of width. ThecurrentBreakpoint will be empty string.

Conditionally Updating State

You can use theshouldUpdate option to conditionally update the state to reduce unnecessary re-renders as below.

constreturnObj=useDimensions({shouldUpdate:({ currentBreakpoint, width, height, entry})=>{// Will only update the state when the target element's width greater than 300pxreturnstate.width>300;},});

Note: WhenupdateOnBreakpointChange andshouldUpdate are used at the same time,shouldUpdate has a higher priority.

Border-box Size Measurement

By default, the hook reports thewidth andheight based on thecontent rectangle of the target element. We can include the padding and border for measuring by theuseBorderBoxSize option. Please note, thewidth andheight states are rely on theResizeObserverEntry.borderBoxSize butit hasn't widely implemented by browsers therefore we need to usepolyfill for this feature.

importuseDimensionsfrom"react-cool-dimensions";import{ResizeObserver}from"@juggle/resize-observer";constApp=()=>{const{ observe, width, height}=useDimensions({useBorderBoxSize:true,// Tell the hook to measure based on the border-box size, default is falsepolyfill:ResizeObserver,// Use polyfill to make this feature works on more browsers});return(<divstyle={{width:"100px",height:"100px",padding:"10px",border:"5px solid grey",}}ref={observe}>{/* Now the width and height will be: 100px + 10px + 5px = 115px */}      Hi! My width is{width}px and height is{height}px</div>);};

How to Share Aref?

You can share aref as follows:

import{useRef}from"react";importuseDimensionsfrom"react-cool-dimensions";constApp=()=>{constref=useRef();const{ observe}=useDimensions();return(<divref={(el)=>{observe(el);// Set the target element for measuringref.current=el;// Share the element for other purposes}}/>);};

Performance Optimization

TheonResize event will be triggered whenever the size of the target element is changed. We can reduce the frequency of the event callback by activating theresponsive mode or implementing our own throttled/debounced function as below. Note that in order to throttle/debounce the function correctly, it will need to be memorized else it will be recreated on every render call.

import{useMemo}from"react";import_from"lodash";constreturnObj=useDimensions({onResize:useMemo(()=>_.throttle(()=>{// Triggered once per every 500 milliseconds},500),[]),});

Working in TypeScript

This hook supportsTypeScript, you can tell the hook what type of element you are going to observe through thegeneric type:

constApp=()=>{const{ observe}=useDimensions<HTMLDivElement>();return<divref={observe}/>;};

💡 For more available types, pleasecheck it out.

API

constreturnObj=useDimensions(options?:object);

Return object

It's returned with the following properties.

KeyTypeDefaultDescription
observefunctionTo set a target element for measuring or re-start observing the current target element.
unobservefunctionTo stop observing the current target element.
widthnumber or nullnullThe width of the target element in pixel. Null while target has not mounted.
heightnumber or nullnullThe height of the target element in pixel. Null while target has not mounted.Z
currentBreakpointstringIndicates the current breakpoint of theresponsive components.
entryobjectTheResizeObserverEntry of the target element.

Parameter

Theoptions provides the following configurations and event callback for you.

KeyTypeDefaultDescription
breakpointsobjectActivates the responsive mode forresponsive components orperformance optimization.
updateOnBreakpointChangebooleanfalseTells the hook to update the state on breakpoint changed.
useBorderBoxSizebooleanfalseTells the hook tomeasure the target element based on the border-box size.
shouldUpdatefunctionTells the hook toconditionally update the state.
onResizefunctionIt's invoked whenever the size of the target element is changed. But inresponsive mode, it's invoked based on the changing of the breakpoint rather than the size.
polyfillResizeObserverIt's used forinjecting a polyfill.

ResizeObserver Polyfill

ResizeObserver has good support amongst browsers, but it's not universal. You'll need to use polyfill for browsers that don't support it. Polyfills is something you should do consciously at the application level. Thereforereact-cool-dimensions doesn't include it.

We recommend using@juggle/resize-observer:

$ yarn add @juggle/resize-observer# or$ npm install --save @juggle/resize-observer

Then inject it by thepolyfill option:

import{ResizeObserver}from"@juggle/resize-observer";const{ width, height}=useDimensions(ref,{polyfill:ResizeObserver});

Or pollute thewindow object:

import{ResizeObserver,ResizeObserverEntry}from"@juggle/resize-observer";if(!("ResizeObserver"inwindow)){window.ResizeObserver=ResizeObserver;// Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45// window.ResizeObserverEntry = ResizeObserverEntry;}

You could use dynamic imports to only load the file when the polyfill is required:

(async()=>{if(!("ResizeObserver"inwindow)){constmodule=awaitimport("@juggle/resize-observer");window.ResizeObserver=module.ResizeObserver;// Only use it when you have this trouble: https://github.com/wellyshen/react-cool-dimensions/issues/45// window.ResizeObserverEntry = module.ResizeObserverEntry;}})();

Articles / Blog Posts

💡 If you have written any blog post or article aboutreact-cool-dimensions, please open a PR to add it here.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Welly
Welly

💻📖🚧
Runar Kristoffersen
Runar Kristoffersen

📖💻🤔
Ricardo Amaral
Ricardo Amaral

💻
Cornelius
Cornelius

🐛
Joseph Horton
Joseph Horton

📖
sirkrisp
sirkrisp

💻

This project follows theall-contributors specification. Contributions of any kind welcome!

About

😎 📏 React hook to measure an element's size and handle responsive components.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

    Contributors8


    [8]ページ先頭

    ©2009-2025 Movatter.jp