React 아코디언 컴포넌트, 검색 페이지 개발 과정

y___h·2023년 4월 12일
0

중첩된 UI를 랜더링하기 위한 아코디언 컴포넌트 개발 과정에 대해 작성해보려한다.

UI: 대댓글이 있는 경우, 댓글에 버튼을 출력하고 버튼 클릭 시 대댓글이 아래로 펼쳐짐

  • 댓글 - 대댓글 input - 대댓글이 한 세트로 나타나야하는 구조
  • Accordian 컴포넌트에서 조건부 스타일 구현 (대댓글에 존재여부에 따라)
  • stack: React, SCSS, classnames

구현 결과


Accordian

구현 과정

  • 상위 컴포넌트에서 API 응답으로 댓글 객체가 담긴 배열을 map method를 통해 accordian 컴포넌트 return
// accordian의 상위 컴포넌트

{reviews &&
  reviews.map((review) => {              
    return (
          <Accordion
             review={review}
             key={review.id}
             movieId={id}
             fetchReviews={fetchReviews}
           />
           );
})}

JSX 구조
button, 대댓글 리스트(article)가 나란히 있는 구조

// accordian.js
...

<댓글 Component />
<대댓글 input />

// 편의상 accordian 부분만 기재

<>
  // button UI: 댓글 개수 ▼
   <button
      className={cx(styles.showCommentsButton, {
              [styles.isShow]: isClicked,
            })}
      onClick={() => setIsShow((cur)=> !cur)}
          >
            댓글 {review.comments.length} 
      <ChevronUp /> // SVG
   </button>

  // 대댓글 list 
   <article className={styles.commentWrap}>
      {review.comments.map((comment) => {
          return (
       		<Comment />
      })}
   </article>
</>

CSS
댓글 버튼의 state에 따라 대댓글 container를 보여주도록 구현


// 댓글 드롭다운 버튼
.showCommentsButton {
  @include m.flex();
  padding: 0 0 16px 16px;
  font-size: 16px;

  > svg {
    transition: transform 0.3s ease-in-out;
  }

// 버튼이 isShow class를 가질 때 
// = 버튼이 눌려진 상태(state)일 때 
  &.isShow {
    > svg {
      transform: rotate(0deg);
    }
    
    // 버튼 옆에 존재하는 대댓글 list 보여주기
    & + .commentWrap {
      visibility: visible;
      max-height: 100vh;
    }
  }
}

// 대댓글 Container
.commentWrap {
  transition: max-height 0.3s ease-in-out, visibility 0.3s ease-in-out;
  visibility: hidden;
  max-height: 0px;
  overflow-y: scroll;
}


검색 페이지

  • 검색 결과 배열이 존재할 경우, grid를 활용하여 출력되는 컴포넌트를 반응형으로 나열.
  • 검색 결과가 없거나 loading 상태에 따라 상이한 UI 출력
  • 영화 카드에 hover 시, overlay를 출력하여 별점과 영화 제목 출력하고, 카드가 위로 움직이며 커지는 애니메이션 추가
  &:hover {
    transform: scale(1.1) translateY(-10px);

    > .overlay {
      background-color: c.$C_BLACK_50;
      visibility: visible;
    }
  }

profile
기록 이사중 🐣

0개의 댓글