Issue

이번 주담대 로직 중 마주친 이슈는 다음과 같습니다.

호 선택.png

<aside> ☝🏻 리스트 형태의 컴포넌트의 height가 정해진 영역을 넘어갈 시 overflow-y: auto 처리와 함께 리스트 하단 부분은 Blur 처리가 되어야 합니다.

</aside>

<aside> ✌🏻 스크롤 이벤트가 일어나 리스트 컴포넌트의 최하단 부분이 보이게 되면 Blur는 사라져야 합니다.

</aside>

ScrollWithBlur 컴포넌트에 들어오는 리스트 컴포넌트의 height는 들어오는 데이터의 양에 따라 가변적인 크기를 가진다는 특징이 있어요.

부모 요소의 height보다 자식 요소의 height의 크기가 더 큰 것을 어떻게 판단할 수 있을까요? 🤔

해당 문제는 useRef를 통해 요소에 접근하여 wrapperHeightchildrenHeight를 가져와 둘의 크기를 비교하는 방식으로 접근했어요.

export const useWithBlur = () => {
	const rootRef = useRef<HTMLDivElement>(null);
  const childrenRef = useRef<HTMLDivElement>(null);

	/** children이 root 요소의 height 넘는지에 대한 상태값 */
  const [isOverflow, setIsOverflow] = React.useState(false);

  useEffect(() => {
    const wrapperHeight = rootRef.current?.clientHeight;

    /** props로 전달받은 children의 height를 측정합니다. */
    const childrenHeight = childrenRef.current?.getBoundingClientRect().height;
    
		if (!wrapperHeight || !childrenHeight) return;
    setIsOverflow(wrapperHeight < childrenHeight);
  }, []);

	return { rootRef, targetRef, isOverflow }
}

useWithBlur 훅을 사용하는 ScrollWithBlur의 컴포넌트 구조는 다음과 같습니다.


export const Wrapper = styled.div`
  position: relative;

  flex: 1;
`;

export const ContentsArea = styled.div`
  position: absolute;
  inset: 0;

  overflow-y: auto;
`;

export const Blur = styled.div`
  position: absolute;
  bottom: 0;

  width: 100%;
  height: 100px;

  background: linear-gradient(180deg, #fff0 0%, #fff 100%);
`;

type ScrollWithBlurProps = React.PropsWithChildren<{}>;

const ScrollWithBlur = ({ children }: WithBlurProps) => {
  const { rootRef, targetRef, isOverflow } = useWithBlur();

  return (
    <Wrapper>
      <ContentsArea ref={rootRef}>
        <div ref={childrenRef}>
          {children}
        </div>
      </ContentsArea>

      {isOverflow && 
       <Blur />
      }
    </Wrapper>
  );
};

export default ScrollWithBlur;