DEV Community

Discussion on: `useWindowSize` React Hook To Handle Responsiveness In JavaScript

Collapse
 
daxsoft profile image
Michael Willian Santos

My aproach is this way: (Someday I'll publish my hooks xD)

import { useState, useEffect, useMemo, useCallback } from 'react'

function getSize(screenSize, config, aspect) {
    if (typeof window === 'undefined') {
        return config
    }

    let { innerWidth, innerHeight, outerWidth, outerHeight } = window

    innerWidth *= aspect[0] || 1
    innerHeight *= aspect[1] || 1

    const orientation = innerWidth > innerHeight ? 'landscape' : 'portrait'
    const ratio = +parseFloat(innerHeight / innerWidth).toFixed(2)

    let difference = 0

    if (screenSize && screenSize.ratio) {
        difference = (screenSize.ratio - ratio) * 100
        if (difference < 0.0) difference *= -1
    }

    return {
        innerWidth,
        innerHeight,
        outerWidth,
        outerHeight,
        ratio,
        difference,
        orientation,
        previous: screenSize,
        aspect,
    }
}

export default function useScreenSize(
    config = {
        innerWidth: 1360,
        innerHeight: 640,
        outerWidth: 1360,
        outerHeight: 640,
        ratio: 0.47,
        orientation: 'landscape',
        difference: 1,
    },
    margin = [1, 1]
) {
    const [screenSize, setScreenSize] = useState(getSize(null, config, margin))

    const handleResize = useCallback(
        () => setScreenSize(getSize(screenSize, config, margin)),
        []
    )

    useEffect(() => {
        window.addEventListener('resize', () => {
            handleResize()
        })

        return () => {
            window.removeEventListener('resize', handleResize)
        }
    }, [])

    return useMemo(
        () => ({
            ...screenSize,
            fullHD:
                screenSize.innerWidth >= 1920 && screenSize.innerHeight >= 1080,
            hd: screenSize.innerWidth >= 1360 && screenSize.innerHeight >= 724,
        }),
        [screenSize]
    )
}

So, you can use like this:

const Page = ({ token }) => {
    const screenSize = useScreenSize({}, [0.9, 1.35])

    return (
        <>
            <Head>
                <title>Assine Aqui | Meu perfil</title>          
            </Head>

            {(screenSize.orientation === 'landscape' ? (
                    <Desktop token={token} profileData={profileData} />
                ) : (
                    <Mobile token={token} profileData={profileData} />
                ))}
        </>
    )
}
Collapse
 
3sanket3 profile image
Sanket Patel

Wow this is an comprehensive one. I think I should sit back and give time to imagine all use cases it covers.