스크롤 시 header에 그림자 보여주기

스크롤 시 header에 그림자 보여주기

스크롤 여부를 확인하는 방법

처음에는 new IntersactionObserver를 적용해 헤더의 바로 다음 요소가 가려지기 시작하면 스크롤이 되었다는 상태값을 바꿔주는 형식을 적용하고자 했었습니다. 하지만, 스크롤이 되는 순간부터 window.scrollY값이 바뀐다는 것을 알게 되었고, 굳이 더 복잡한 방식을 적용할 필요가 없다고 생각해 window.scrollY를 이용해 처리를 하도록 했습니다.

그리고 스크롤이 되는 상황에 대해서 화면이 인지하고 상태를 바꿔야하기 때문에, window.onscroll에 함수를 적용해주었습니다.

const useIsTopState = () => {
  const [isTop, setIsTop] = useState(true);
  // 페이지의 최상단에 있는지를 나타내는 state

  window.onscroll = () => {
    setIsTop(!window.scrollY);
    // 스크롤되는 화면의 최상단에 있을 시 scrollY = 0 이므로 isTop이 true가 됨
  };

  return isTop;
};

상태를 받은 header의 스타일 변경하기

isTop 상태를 받은 header가 true일 때에만 그림자를 보여주지 않도록 설정을 해, 스크롤이 되는 상황에서 지속적으로 그림자를 보여주도록 설정했습니다.

const Chatrooms = () => {
	...
  const isTop = useIsTopState();
	// isTop 상태를 받아옴
	...
	<S.Wrapper>
    <S.HeaderWrapper isTop={isTop}>
    // 사용하고자 하는 header에 적용
      <TopFixedWarning text='채팅 연결 끊김' otherStyle={S.TopFixedWarningStyle} />
      <S.Header onClick={() => setIsConnected(!isConnected)}>
	...
export const HeaderWrapper = styled.div<{ isTop: boolean }>`
  ${({ theme: { colors, defaultWidth, defaultPadding }, isTop }) => css`
    ${defaultWidth};
		...
    transition: all 0.3s;
    // 그림자가 부드럽게 사라지고 나타나기 위해 설정

    ${!isTop &&
    css`
      box-shadow: 2px 4px 6px rgba(0, 0, 0, 0.08);
      // 최상단에 있을 때에만 그림자가 안 보이도록 설정
    `}

위 코드들을 적용해줌으로써, 스크롤 상황에 대한 그림자 표현을 할 수 있었습니다.

window.onscroll 값을 초기화해야 하는지

useEffect(() => {
  return () => {
    window.onscroll = null;
  };
}, []);

기존에는 위와 같이 화면을 나가는 경우 window,onscroll을 초기화하도록 설정을 해주었습니다. 초기화를 하지 않는 경우, 이 함수가 사용되지 않는 곳에서도 지속적으로 함수가 작동해 불필요한 연산이 될 것이라는 예상 때문이었습니다. 하지만, 아래와 같이 useEffect가 없어도 화면 전환 시 onScroll의 함수는 없어진다는 것을 확인할 수 있었습니다. (console.log()로 확인)