
큰 Container는 display: flex와 flex-wrap: wrap을 설정하여, 내부 요소들이 공간을 채우면 자동으로 다음 줄로 이동하도록 구현했습니다.
이후 Shop All 요소에는 width: 100%를 지정하여 한 줄 전체를 차지하도록 만들고, 그 다음 줄부터 왼쪽에는 카테고리 리스트, 오른쪽에는 상품 리스트(ProductList)가 배치되도록 구성했습니다.
리스트 영역은 display: flex에 flex-direction: column을 적용하여 세로 방향으로 나열되도록 했고, 드롭다운 메뉴도 포함시켜 구현했습니다.
상품 리스트 영역(ProductList)은 display: grid를 사용해 격자 형태로 배치하였습니다.
.sort ul {
max-height: 0;
overflow: hidden;
transition: 0.5;
width: 100%;
background-color: var(--dark-colors-white-dark);
margin-top: var(--fs8);
padding-left: 0;
position: absolute;
}
.sort.active ul {
max-height: 200px;
}
드롭다운 메뉴를 구현하면서, ul 요소에 max-height: 0과 overflow: hidden 속성을 주어 초기에는 메뉴가 보이지 않도록 설정했습니다.
이 ul은 드롭다운이 펼쳐질 때 다른 요소들의 레이아웃에 영향을 주지 않도록 하기 위해 position: absolute;를 적용했습니다. 이렇게 하면 드롭다운이 열릴 때도 주변 요소들이 밀리거나 움직이지 않고, 원하는 위치에 겹쳐서 표시할 수 있습니다.
드롭다운은 아래를 향한 아이콘을 클릭할 때 isActive 상태를 true로 변경하여 ul에 active 클래스를 추가하고, 이를 통해 max-height를 증가시켜 메뉴가 자연스럽게 펼쳐지도록 구성했습니다.
아래 이미지는 max-width: 1100px일 때의 레이아웃을 보여줍니다.

만약 ul에 position: absolute를 주지 않는다면, 드롭다운이 펼쳐질 때 옆에 배치된 리스트들도 함께 아래로 밀리게 되어 레이아웃이 깨지게 됩니다. 따라서 드롭다운이 레이아웃 흐름에 영향을 주지 않도록 하기 위해 position: absolute;를 적용한 것입니다.
React.memo()는 리액트에서 컴포넌트 성능을 최적화하기 위한 고차 컴포넌트입니다. 주요 목적은 불필요한 리렌더링을 방지하여 애플리케이션의 성능을 향상시키는 것입니다.
함수 내 계산 비용이 큰 연산을 캐싱하여 불필요한 재계산 방지
(계산량이 많은 함수 호출 결과 (ex: 정렬, 필터링 등))
React.memo: 컴포넌트를 감싸서 렌더링을 막음
useMemo: 값을 캐싱해서 재계산을 막음
둘 다 성능 최적화를 위한 도구지만 하나는 컴포넌트 하나는 값(연산 결과)를 대상으로 한다는 점이 가장 큰 차이