상세 컨텐츠

본문 제목

상품 리스트 페이지 코드 리뷰

성장일지

by 모모87 2024. 6. 25. 13:58

본문

 

useEffect / useState 사용하면서 점점 어려워지는 리액트

허심탄회한 코드 리뷰 남겨보면서 리마인드 해봅니다.

 

 

 

이번 미션은 페이지에 api 가져오고 페이지 네이션까지 해야 했다.

점점 하기 싫어지는 공부단계

하지만 꼭 알아야는 개념이기 때문에

꾸역꾸역 해봅니다.

 


 

1. 스위치문 변경

const getPageSize = () => {  
    const width = window.innerWidth;
      if (width < 768) {
        // Mobile viewport
        return 4;
      } else if (width < 1200) {
        // Tablet viewport
        return 6;
      } else {
        // Desktop viewport
        return 10;
      }
};

 

if문을 활용해서 사이즈 변경 시 상품을 보여주는 값을 다르게 지정했다.

const getPageSize = () => {
  const width = window.innerWidth;
  switch (true) {
    case (width < 768):
      // Mobile viewport
      return 4;
    case (width < 1200):
      // Tablet viewport
      return 6;
    default:
      // Desktop viewport
      return 10;
  }
};

 

멘토님께서 이렇게 해야 깔끔하고 보기 좋다고 하셨다.

스위치문을 잘 써봐야겠다.

 


 

2. 불필요한 state 생략 / 상수화 관리

 

  const [page, setPage] = useState(1); 
  const [pageSize, setPageSize] = useState(getPageSize()); 
  const [totalPageNum, setTotalPageNum] = useState(0);

  const [menuOpen, setMenuOpen] = useState(false);
  const [menuLabel, setMenuLabel] = useState('최신순');

 

menuOpen, menuLabel을 각각 넣어서 state 값을 관리했다.

const [orderBy, setOrderBy] = useState('recent'); // 하나의 상태로 관리

return (
...
<button onClick={toggleMenu} className="dropdown-toggle" type="button">
{orderBy === 'recent' ? "최신순" : "좋아요순"}
</button>
...
)

 

orderBy 하나로 상태값을 변경할 수 있다.

혹은

const SORT_MENU_INFO = {
  RECENT: {
    label: '최신순',
    orderLabel: 'recent'
  },
 FAVORITE: {
    label: '좋아요순',
    orderLabel: 'favorite'
 }
}

// 접근 예시
const [menuLabel, setMenuLabel] = useState(SORT_MENU_INFO.RECENT.label));
const [orderBy, setOrderBy] = useState(SORT_MENU_INFO.RECENT.orderLabel);

const handleNewestClick = () => {
    setMenuLabel(SORT_MENU_INFO.RECENT.label);
    setMenuOpen(false);
    setOrderBy(SORT_MENU_INFO.RECENT.orderLabel);
};

 

요렇게 '최신순' / '좋아요 순'이나 'recent' / 'favorit' 같은 항목들은
컴포넌트 내에서 반복적으로 사용하기도 하고, 변하지 않는 항목들이기 때문에 상수화하여
관리하면 유지보수에 많은 도움이 된다.

 


 

3. 반복되는 리스트는 map 활용

  const handleNewestClick = () => {
    setMenuLabel('최신순');
    setMenuOpen(false);
    setOrderBy('recent');
  };

  const handleFavoriteCountClick = () => {
    setMenuLabel('좋아요순');
    setMenuOpen(false);
    setOrderBy('favorite');
  };

 

요렇게 반복되는 리스트의 경우에도 map을 사용할 수 있다고 한다.

 

 

 

const handleSortMenuClick = (sortMenu) => {
    setMenuLabel(sortMenu.label);
    setMenuOpen(false);
    setOrderBy(sortMenu.orderLabel);
}
  
<ul className={`dropdown-menu ${menuOpen ? 'open' : ''}`}>
    {Object.entries(SORT_MENU_INFO).map(([key, value]) => {
      return (
        <li key={key}>
          <button
            onClick={() => handleSortMenuClick(value)}
            className="dropdown-item"
          >
            {value.label}
          </button>
        </li>
      );
    })}
</ul>

 

덕분에 코드 반복 사용을 줄였다.


 

4. pagination 에는 a 태그 말고 button을 사용할 것

return (
    <ul className="pagination">
      <li className="prev">
        <a className="page-link"
          disabled={activePageNum === 1}
          onClick={() => onPageChange(activePageNum - 1)}
          href="#none" title='이전'></a>
      </li> 
      {pages.map((page) => (
        <li>
          <a href="#none"
          key={page}
          className={`page-link ${
            activePageNum === page ? "on" : ""
          }`}
          onClick={() => onPageChange(page)}
          >{page}</a>
        </li> 
      ))}
      <li className="next">
        <a className="page-link" disabled={activePageNum === totalPageNum}
        onClick={() => onPageChange(activePageNum + 1)} href="#none" title='다음'></a>
      </li>
    </ul>
  );
}

 

퍼블리싱 하면서 습관적으로 a태그를 많이 사용하는데

페이지 이동이 아닌 경우는 버튼 태그를 추천하셨다.

 

<ul className="pagination">
  <li>
    <button
      className="prev page-link"
      disabled={activePageNum === 1}
      onClick={() => onPageChange(activePageNum - 1)}
      title="이전"></button>
  </li>
  {pages.map(page => (
    <li>
      <button
        key={page}
        className={`page-link ${activePageNum === page ? 'on' : ''}`}
        onClick={() => onPageChange(page)}>
        {page}
      </button>
    </li>
  ))}
  <li>
    <button
      className="page-link next"
      disabled={activePageNum === totalPageNum}
      onClick={() => onPageChange(activePageNum + 1)}
      title="다음"></button>
  </li>
</ul>

 

깔끔해진 버튼들...

 


 

이렇게 미션 코드 리뷰를 또 마무리 했다.

솔직히 모든 개념을 다 마스터 하진 못했지만

반복 사용하면서 언젠가는 안보고도 술술 클린코드가 써내려가지길

바래본다.

 

어설픈 리뷰일진 모르지만

이렇게 조금이라도 기록하면서

리마인드를 한다.

 

점점 기록하는 스킬도 좋아지는 나를 기대해보며...

반응형

'성장일지' 카테고리의 다른 글

리액트에서 배열을 렌더링할 때 key를 써야 하는 이유  (0) 2024.06.29
리액트 Virtual DOM  (0) 2024.06.29
HTTP 메소드  (0) 2024.06.21
렉시컬 스코프  (0) 2024.06.21
리액트 명령어 정리  (0) 2024.06.19

관련글 더보기