programing

React에서 화면 크기가 모바일로 변경되었는지 감지하는 방법

linuxpc 2023. 4. 6. 21:10
반응형

React에서 화면 크기가 모바일로 변경되었는지 감지하는 방법

React에서 웹 앱을 개발 중인데 상태를 변경하려면 화면 크기가 모바일 중단점에 진입한 시점을 감지해야 합니다.

특히 사용자가 모바일모드로 이행했을 때 sidenav를 축소하고 컴포넌트 내의 상태에 저장되어 있는 부울로 제어해야 합니다.

컴포넌트 마운트 후에 이벤트청취자를 추가했습니다.

componentDidMount() {
    window.addEventListener("resize", this.resize.bind(this));
    this.resize();
}

resize() {
    this.setState({hideNav: window.innerWidth <= 760});
}

componentWillUnmount() {
    window.removeEventListener("resize", this.resize.bind(this));
}

편집: 상태 업데이트를 저장하기 위해 "크기 조정"을 조금 변경했는데, 창 너비가 변경되었을 때만 업데이트되도록 했습니다.

resize() {
    let currentHideNav = (window.innerWidth <= 760);
    if (currentHideNav !== this.state.hideNav) {
        this.setState({hideNav: currentHideNav});
    }
}

업데이트: 후크를 사용할 시간입니다!컴포넌트가 기능하고 있고 후크를 사용하는 경우useMediaQuery후크, 발신기지react-responsive패키지.

import { useMediaQuery } from 'react-responsive';

...

const isMobile = useMediaQuery({ query: `(max-width: 760px)` });

이 후크를 사용하면 화면 크기 조정 시 is Mobile이 업데이트되고 컴포넌트가 다시 렌더링됩니다.훨씬 좋아!

const [isMobile, setIsMobile] = useState(false)
 
//choose the screen size 
const handleResize = () => {
  if (window.innerWidth < 720) {
      setIsMobile(true)
  } else {
      setIsMobile(false)
  }
}

// create an event listener
useEffect(() => {
  window.addEventListener("resize", handleResize)
})

// finally you can render components conditionally if isMobile is True or False 

React(16.8.0+)에서의 후크 사용방법:https://stackoverflow.com/a/36862446/1075499

import { useState, useEffect } from 'react';

function getWindowDimensions() {
  const { innerWidth: width, innerHeight: height } = window;
  return {
    width,
    height
  };
}

export default function useWindowDimensions() {
  const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());

  useEffect(() => {
    function handleResize() {
      setWindowDimensions(getWindowDimensions());
    }

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

  return windowDimensions;
}

이는 @Ben Cohen의 답변과 동일하지만 eventListner에 함수를 연결한 후 componentWillUnmount에서도 삭제합니다.

constructor() {
  super();
  this.state = { screenWidth: null };
  this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
}

componentDidMount() {
    window.addEventListener("resize", this.updateWindowDimensions());
}

componentWillUnmount() {
    window.removeEventListener("resize", this.updateWindowDimensions)
}

updateWindowDimensions() {
   this.setState({ screenWidth: window.innerWidth });
}

방금 이 문제에 대한 npm 패키지를 발행했습니다.https://www.npmjs.com/package/react-getscreen에서 확인하세요.

import React, { Component } from 'react';
import {withGetScreen} from 'react-getscreen'

class Test extends Component {
  render() {
    if (this.props.isMobile()) return <div>Mobile</div>;
    if (this.props.isTablet()) return <div>Tablet</div>;
    return <div>Desktop</div>;
  }
}

export default withGetScreen(Test);

//or you may set your own breakpoints by providing an options object

const options = {mobileLimit: 500, tabletLimit: 800}
export default withGetScreen(Test, options);

이 클래스를 사용하여 CSS를 아카이브하는 첫 번째 방법은 여러 가지가 있습니다.

@media screen and (max-width: 576px) {}

이 태그 내의 모든 클래스는 화면이 같거나 576px 미만일 때만 표시됩니다.

두 번째 방법은 이벤트 청취자를 사용하는 것입니다.

이와 같은 것

 constructor(props)
    {
        super(props);

        this.state = {
            isToggle: null
        }

        this.resizeScreen = this.resizeScreen.bind(this); 
    }
    
    
     componentDidMount() {

        window.addEventListener("resize", this.resizeScreen());

    }
    
    
    resizeScreen() {
        if(window.innerWidth === 576)
        {
            this.setState({isToggle:'I was resized'});
        }
        
    }

이벤트 청취자라도 나는 여전히 CSS 방식을 선호한다. 왜냐하면 우리는 더 이상의 js 코딩 없이 여러 화면 크기를 사용할 수 있기 때문이다.

도움이 됐으면 좋겠네요!

react-screente-hook 라이브러리를 사용하면 이 작업을 즉시 수행할 수 있습니다.https://www.npmjs.com/package/react-screentype-hook

다음과 같이 기본 중단점을 사용할 수 있습니다.

const screenType = useScreenType();

screenType의 모양은 다음과 같습니다.

  {
    isLargeDesktop: Boolean,
    isDesktop: Boolean,
    isMobile: Boolean,
    isTablet: Boolean
  }

또는 커스텀 브레이크 포인트를 다음과 같이 설정할 수도 있습니다.

const screenType = useScreenType({
    mobile: 400,
    tablet: 800,
    desktop: 1000,
    largeDesktop: 1600
  });

Next.js의 경우

Here is a custom hook
import { useState, useEffect } from 'react';

export default function useScreenWidth() {

    const [windowWidth, setWindowWidth] = useState(null);

    const isWindow = typeof window !== 'undefined';

    const getWidth = () => isWindow ? window.innerWidth : windowWidth;

    const resize = () => setWindowWidth(getWidth());

    useEffect(() => {
        if (isWindow) {
            setWindowWidth(getWidth());
      
            window.addEventListener('resize', resize);
       
            return () => window.removeEventListener('resize', resize);
        }
    //eslint-disable-next-line
    }, [isWindow]);

    return windowWidth;
}

컴포넌트에서는 뷰포트의 폭 크기를 반환하며, 이 크기를 지정된 숫자 값과 비교할 수 있습니다.

const widthSize = useScreenWidth()

const mobileWidth = 400

if(widthSize > mobileWidth){ 
    //logic for desktop
}

if(widthSize <= mobileWidth){ 
    //logic for mobile
}

Functional Component(기능 컴포넌트)에서는 화면 크기를 사용하여 검출할 수 있습니다.주제 및 사용 MediaQuery.

const teme = useTheme();
const xs = MediaQuery(theme.breakpoints.only('xs'))를 사용합니다.
sm =.only const sm = MediaQuery(teme.breakpoints.only('sm')))입니다.
md = const md = use MediaQuery(teme.breakpoints.only('md')));
lg = 사용; const lg = MediaQuery(teme.breakpoints.only('lg')) 사용.
xl = const xl = useMediaQuery(teme.breakpoints.only('xl')));

언급URL : https://stackoverflow.com/questions/44480053/how-to-detect-if-screen-size-has-changed-to-mobile-in-react

반응형