지금 진행중인 프로젝트는 모바일 기반으로, 추후 데스크톱 버전을 기획하고는 있지만,
우선은 모바일 우선으로 개발하고, 그 화면을 데스크톱에서 자연스럽게 보여주기 위해 전체 레이아웃을 만드는 작업이 필요했다.
위 사진에 나오는 배경 색상도 모두 지정된 색상으로, 해당 페이지를 <CommonLayout>이라는 공통컴포넌트로 감싸주면 바뀌게 되어있다.
아래는 CommonLayout코드 (개발 과정이라 리팩토링은 필요하다)
import React, { useEffect } from 'react';
import {
StLayoutBody,
StLayoutOuter,
StLayoutSection,
StSlidingHeader,
} from './CommonLayout.styles';
import { FloatingFooter } from './components/FloatingFooter/FloatingFooter';
interface CommonLayoutProps {
children: React.ReactNode;
header?: React.ReactNode;
footer?: React.ReactNode;
headerHeight?: string;
footerHeight?: number;
hideHeader?: boolean;
backgroundColor?: string;
}
/**
* CommonLayout
* @param children 본문 컨텐츠는 children에 넣어줄것
* @param 선택사항 header, prop으로 JSX 넘겨줄것
* @param 선택사항 footer, prop으로 JSX 넘겨줄것, 사용시 footerSpacer를 사용해야함
* @param 선택사항 headerHeight 딘위까지 입력해야함, 기본값 50px
* @param 선택사항 hideHeader 스크롤시 헤더 숨김 여부. 기본값 true
* @param 선택사항 backgroundColor 배경색 지정. 기본값 #fff
*/
export const CommonLayout: React.FC<CommonLayoutProps> = ({
children,
header,
footer,
headerHeight = '50px',
hideHeader = true,
backgroundColor = '#F7F7F7',
}) => {
const [isShow, setIsShow] = React.useState(true);
const [prevPosition, setPrevPosition] = React.useState(0);
const scrollRef = React.useRef<HTMLDivElement>(null);
headerHeight = header ? headerHeight : '0px';
useEffect(() => {
const onScroll = () => {
if (scrollRef.current) {
const { scrollTop } = scrollRef.current;
// console.log(scrollTop + '❤️🩹');
if (scrollTop > prevPosition) {
setIsShow(false);
} else {
setIsShow(true);
}
setPrevPosition(scrollTop);
}
};
if (scrollRef.current && hideHeader) {
scrollRef.current.addEventListener('scroll', onScroll);
}
return () => {
if (scrollRef.current) {
scrollRef.current.removeEventListener('scroll', onScroll);
}
};
}, [prevPosition]);
return (
<StLayoutOuter>
<StLayoutBody>
{header && <StSlidingHeader $isShow={isShow}>{header}</StSlidingHeader>}
<StLayoutSection
ref={scrollRef}
$headerHeight={headerHeight}
$backgroundColor={backgroundColor}
>
{children}
</StLayoutSection>
{footer && <FloatingFooter>{footer}</FloatingFooter>}
</StLayoutBody>
</StLayoutOuter>
);
};
근데 화면전환시에 잠깐잠깐씩 이 레이아웃이 적용이 안된 화면이 남아있어서, 순간 깜박임 같은 현상이 나타나서 하나씩 제거를 해보았다.
처음에 상세페이지에서 loading시 배경색상, 스타일링이 적용이 안되어 있었던 부분을 수정했고,
여러 화면을 돌아다니다가 로그인 화면에서 순간적으로 흰 화면이 나오는것을 발견했다.
첫번째는 카카오 콜백 페이지였고, 스타일링이 적용된 CommonLayout으로 감싸주니 사라졌다.
하지만 많이 줄어들었지만, 흰 화면이 0.1초정도 나타나는 현상이 남아있었다.
성능측정으로 녹화를 해도 잘 보이지 않을 정도의 순간적인 깜박임이다.
경로를 계속 따라가다 발견한 것이
Navigate가 함수인줄 알았는데 잘 보니 컴포넌트이다.
React-router-dom에서 제공하는, 사실상 페이지 이동이라는 기능이 내장된 빈 컴포넌트이다.
(즉, 여기선 빈 페이지가 되어버림)
이렇게 감싸주니 해결이 되었다.
사실 이렇게 하는것보다, Router나 App 전체를 감싸주면 한번에 해결되지만
CommonLayout 컴포넌트에 있는 여러가지 속성값(header, footer의 종류와 속성값) 페이지마다 다르게 들어가야해서,
코드상으로는 전체 감싸는 코드 따로, 각각 설정해주는 코드 따로 하면 더 복잡해져서,
이런 식으로 작업을 하게 되었다.
하지만, 그렇게 되면 배경부분도 매번 랜더링이 새로 들어가는게 되어버려서,
추후 전체를 감싸는게 더 유리할것으로 예상되어서
이 수정사항은 우선 취소하고, 여기에만 남겨두었다.
다음주 최적화때는 랜더링 성능 측정으로 확인해보고,
배경이 매번 재 랜더링이 된다면,
레이아웃 구조를 변경해서 (props값 변화는 없도록 해서 동료 코드에는 변화가 없도록 할 예정!)
최적화를 진행할 예정이다.