본문 바로가기
FrontEnd/Next.js

[Next.js] useMediaQuery 모바일/데스크탑 구분 훅 (feat. window is not defined)

by 위그든씨 2024. 9. 23.

window.matchMedia를 사용하여 미디어 쿼리 변경을 감지하고 이벤트 리스너를 추가

matchMedia 객체를 통해 매개변수로 넘어온 query에 맞춰 매치가 되는지 true false 반환

현재 기본 값으로 최대가 768px인지를 판단하는 쿼리가 들어왔으므로 

모바일이라면 true, 데스크탑이라면 false를 반환해준다.

import { useState, useEffect } from "react";

export function useMediaQuery(query: string = "(max-width: 768px)"): boolean {
  const [matches, setMatches] = useState<boolean>(false);

  useEffect(() => {
    const getMatches = (query: string): boolean => {
      // window is not defined가 뜨는 ssr 이슈 막기
      if (typeof window !== "undefined") {
        return window.matchMedia(query).matches;
      }
      return false;
    };

    function handleChange() {
      setMatches(getMatches(query));
    }

    // 초기값 세팅
    handleChange();

    const matchMedia = window.matchMedia(query);


    matchMedia.addEventListener("change", handleChange);

	// 클린업 시 이벤트 삭제
    return () => {
      matchMedia.removeEventListener("change", handleChange);
    };
  }, [query]);

  return matches;
}