[React / Typescript] IOS safari 상태바 색상 변경 / 커스텀 훅을 이용한 동적 처리
Code/React - Node

[React / Typescript] IOS safari 상태바 색상 변경 / 커스텀 훅을 이용한 동적 처리

반응형

 

문제 : 반응형 웹 서비스 구현 중 IOS의 사파리 브라우저 환경에서 상단바가 페이지 배경색과 일치하지 않음을 확인

브라우저의 상단바 색상을 해당 페이지의 배경색과 동일하게 변경을 해야 했고, 페이지 별 상이한 배경을 갖고 있는 경우가 있기에 이를 핸들링할 수 있어야 했다.

반응형

 

1. 상태바 색상 변경 (change safari status bar color)

- index.html

<meta id="status-bar" name="theme-color" content="FFFFFF" />

html 파일 내부에 meta 태그를 위와 같이 작성할 경우 content의 색상을 고정으로 가지고 있을 수 있다.

 

나는 페이지 별로 다른 색상의 상태바를 보여주길 원했기에 커스텀 훅을 생성했다.

 

2. Custom hook 커스텀 훅

추후 유지 보수를 생각했을 때, 기본으로 설정된 흰색이 아닌 다른 색상이 필요한 경우만을 예외로 두어 쉽게 관리하고 싶었기에 아래와 같이 Map 객체의 key에 기본 색이 아닌 상태바를 가진 페이지의 path를 저장했고, value에는 페이지에 해당하는 색상을 저장했다.

이건 다수의 페이지와 색상이 추가되는 경우를 대비한 개인적인 코드이기에 정도는 아니다.

export const STATUS_BAR_COLOR = {
  GENERAL: '#FFFFFF',
  FIRST_PAGE: '#F2F2F2',
};

export const STATUS_BAR_COLOR_USAGE = new Map([
  ['/first/page', STATUS_BAR_COLOR.FIRST_PAGE],
]);

 

 

- useStatusBarColor.ts 

import {useLayoutEffect, useMemo} from 'react';
import {useLocation} from 'react-router-dom';

const useStatusBarColor = () => {
  const location = useLocation();

  const statusBarColor = useMemo(
    () =>
      STATUS_BAR_COLOR_USAGE.get(location.pathname) ?? STATUS_BAR_COLOR.GENERAL,
    [location],
  );

  useLayoutEffect(() => {
    const metaElement = document.getElementById('status-bar');
    if (!metaElement) return;
    (metaElement as HTMLMetaElement).content = statusBarColor;

  }, [statusBarColor]);

};

export default useStatusBarColor;

페이지의 이동을 전역으로 감지하면서 다이나믹한 색상이 반영될 수 있는 것을 목표로 한 코드이다.

 

react-router-dom 라이브러리의 useLocation 훅을 사용하여 location 객체를 가져오고,

statusBarColor 상수에서는 색상 커스텀이 필요한 페이지인 경우 map 객체에 저장된 값을 가져오고, 값이 없다면 기본 색상을 가진다.

dom이 그려지기 전에 최대한 빠른 렌더링을 원했기에 useLayoutEffect 훅을 통해 meta 태그에 사용한 id를 이용 dom 명령어로 html element 에 접근했다. 

메타 태그 컨텐츠의 색상을 강제로 변경 ->  location path가 변경되는 경우 디펜던시로 감지하여 작동할 수 있도록 구현한 뒤 작동을 원하는 렌더 트리의 최상단 컴포넌트에서 해당 훅을 호출할 경우 정상 작동하는 것을 확인할 수 있다.

 

 

참고 : https://benborgers.com/posts/ios-15-safari-theme-color

반응형