-
20221208 TIL 리팩토링을 조금 더 편하게TIL 2022. 12. 8. 23:02
2주에 걸쳐 과제 구현을 완료했다!
과제를 완료했기 때문에 어제 작업했던 페이지네이션 컴포넌트 리팩토링을 진행하였다.
이때까지 리팩토링을 할 때 리팩토링을 원래 파일에서 하다보면 혼란스러웠던 경우가 많았다.그리고 기존 파일에서 작업할 때 작업을 하는데도 어려움이 느껴졌었기 때문에
리팩토링을 제대로 하는 경우에 다른 방식으로 접근을 해야겠다는 생각을 했었고,
예전에 홀맨님께 조언을 구했었다.
그런데 그동안 리팩토링을 제대로 할 일이 많지 않았기 때문에 그 방식을 한동안 까먹고 있었다.
오늘은 어제 작성한 무지막지한 페이지네이션 컴포넌트 코드를 제대로 리팩토링을 해야됐는데,
어떻게 하면 조금 편하게 리팩토링을 할 수 있을까 고민하는 중에
홀맨님이 말씀해주신 방식이 떠올랐다.
바로 기존 파일을 복사해서 복사한 파일에서 리팩토링을 진행하는 것이었다.
테스트 코드는 이미 있기 때문에 안심하고 리팩토링을 진행할 수 있었고, 파일을 복사해서 중복되는 로직을 분리했다.
어제 생각해본 대로 결국 페이지네이션 컴포넌트에서 쓰일 값들을 배열로 뽑아내기만 하면
컴포넌트를 매우 작게 만들 수 있기 때문에 페이지네이션 컴포넌트에서 쓰일 값들(페이지 값들)을 뽑아내는 함수를 만드는 것부터 시작했다.
두 페이지 사이 값이 2이상 차이나는 경우 ... 으로 표시를 해야했는데,
리액트에서 map을 돌리는 경우 고유한 key가 필요하다.
...는 최대 두 개가 있을 수 있고, 페이지 값들은 양수이기 때문에 key를 -1과 -2를 주었고,
여러 번의 리팩토링 끝에 아래와 같이 리팩토링할 수 있었다.
동기분의 리팩토링 중의 코드를 보고 복잡해보인다는 말을 듣고 rangeOf 메서드를 분리할 수 있었다.
지금도 깔끔하진 않지만 동기분의 말씀 덕분에 메서드를 하나 더 분리할 수 있어 조금 더 깔끔해진 것 같다.
const rangeOf = ({ size, start = 0 }) => [...Array(size).keys()].map((i) => i + start); const pageValues = ({ totalPages, currentPage }) => { if (totalPages < 8) { return [...rangeOf({ size: totalPages })]; } if (currentPage < 5) { return [...rangeOf({ size: 5 }), { key: -1, value: '...' }, totalPages - 1]; } if (totalPages - currentPage < 4) { return [0, { key: -1, value: '...' }, ...rangeOf({ size: 5, start: totalPages - 5 })]; } return [0, { key: -1, value: '...' }, ...rangeOf({ size: 3, start: currentPage - 2 }), { key: -2, value: '...' }, totalPages - 1]; }; export default function Pagination({ url, totalPages, currentPage = 1 }) { const navigate = useNavigate(); const handleClickPrevious = () => { navigate(`${url}?page=${currentPage - 1}`); }; const handleClickNext = () => { navigate(`${url}?page=${Number(currentPage) + 1}`); }; if (!totalPages) { return null; } const pages = pageValues({ totalPages: Number(totalPages), currentPage: Number(currentPage), }); return ( <ul> <li> <button type="button" title="previous" name="previous" disabled={currentPage < 2} onClick={handleClickPrevious} > previous </button> </li> { pages .map((page) => ( typeof page === 'number' ? ( <li key={page}> <Link to={`${url}?page=${page + 1}`} selected={Number(currentPage) === page + 1} > {page + 1} </Link> </li> ) : ( <li key={page.key}> <p> {page.value} </p> </li> ) )) } <li> <button type="button" title="next" name="next" disabled={currentPage > totalPages - 1} onClick={handleClickNext} > next </button> </li> </ul> ); }
항상 복잡해 보이면 분리할 수 있는 메서드가 있는지 꼭 확인하자.
그리고 이번에 리팩토링할 때 복사를 해서 리팩토링하는 것이 매우 편함을 느꼈다.
테스트 코드가 있어서 마음놓고 리팩토링을 할 수 있었고, 기존 코드도 이미 있기 때문에 마음을 놓고 리팩토링을 할 수 있었던 것 같다.
앞으로도 리팩토링할 때 기존 파일을 복사해서 수정해서 테스트가 통과되면
기존 파일을 리팩토링한 파일로 대체하는 방식으로 작업하면 좋을 것 같다!
'TIL' 카테고리의 다른 글
20221210 TIL 좌충우돌 배포하기 (1) 2022.12.10 20221209 TIL 배포를 하면 고려하지 못했던 점들을 확인할 수 있다 (0) 2022.12.09 20221207 TIL 트렌디한 페이지네이션 구현하기 (0) 2022.12.07 20221206 TIL 평정심 유지하기 (0) 2022.12.06 20221205 TIL DTO in DTO (0) 2022.12.05