[TIL] 240526 (React 가계부 시간순 정렬 / 날짜 input 자동 변경)

·2024년 5월 26일

TIL

목록 보기
53/268
post-thumbnail

🥞 오늘 한 일

  • 리액트 숙련 개인과제
    • 지출 데이터 시간순 정렬
    • 각 월 클릭 시 날짜 input 해당 월로 변경
    • 새 지출 추가 후 날짜 input 현재 월로 변경
    • 과제 질문 3번 답변

🍽️ 문제 해결

지출 데이터 시간순 정렬

선택 구현 사항으로 sort 로직을 사용하여 지출 데이터 정렬을 시간순 혹은 종류별로 정렬하는 과제가 있었다. 나는 시간순으로 정렬을 해보았다.

STEP 1

expensesList.sort() // error

// 오류 내용
TypeError: Cannot assign to read only property '0' of object '[object Array]'

우선 정렬을 해주려면 map을 하기 전에 sort를 해주려 했는데, 오류가 났다.
찾아보니, read only인 데이터를 바꾸려고 했기 때문에 에러가 발생한 것이다. 때문에 expensesList를 그대로 사용할 수는 없겠다는 생각이 들었고, 때문에 스프레드 연산자를 사용해 새로운 배열에서 sort를 진행해주었다.

STEP 2

그 다음으로 sort 로직 안에서 뭘 return하여 정렬을 해줄 것인가가 문제였다. 처음에는 며칠인지만 splice해서 정렬을 해주려고 했지만, 그렇게 할 경우 연도가 다를 때 제대로 정렬이 되지 않는 문제가 생긴다. (같은 월이지만 24년의 1일보다 23년의 31일이 더 최신 날짜로 나오게 된다.) 때문에 그냥 date를 그대로 숫자로 만들어 계산해주는 게 제일 좋은 방법이라는 생각이 들었다.

[...expensesList]
  .sort((a, b) => {
    return b.date.split("-").join("") - a.date.split("-").join("");
  })

각 date 내의 -를 삭제한 값으로 내림차순 계산을 하니 제대로 시간순 정렬이 되었다. 과제가 해결되었다.

날짜 input 현재 월로 설정

일단 나중에 하자고 미뤄뒀던 기능을 설정했다. 각 월 클릭 시 날짜 input을 해당 월로 변경하고, 새 지출 추가 후 날짜 input을 현재 월로 변경하는 기능이다.

useEffect(() => {
  setDate(() => {
    return selectedMonth >= 10
      ? `2024-${selectedMonth}-01`
    : `2024-0${selectedMonth}-01`;
  });
}, [selectedMonth]);

selectedMonth가 바뀔 때마다 새롭게 setDate를 설정해주었다. 여기서 삼항 연산자를 사용해준 이유는 10월 이상일 때와 미만일 때의 설정이 달라야 YYYY-MM-DD 스타일로 나타나기 때문에 사용했다.
일단 여기까지 하고 지출 내역을 추가해봤는데, 왜인지 2024-01-01로 초기화가 되는 것이다. selectedMonth가 1로 바뀌지도 않았는데...? 알고보니 내가 지출 추가 시 임의로 해당 날짜로 설정해준 게 문제였다.

setDate("2024-01-01");

이러니 당연히 초기화가 될 수밖에 없었던 것. 때문에 해당 setDate도 위처럼 바꿔주었다.

setDate(() => {
  return selectedMonth >= 10
    ? `2024-${selectedMonth}-01`
  : `2024-0${selectedMonth}-01`;
});

문제가 해결되었다.

과제 질문 답변

어제에 이어, 과제 질문 중 남은 3번의 답변이다.

  1. 지출을 등록/수정 하는 과정에서 useState 와 useRef 를 둘다 사용해봤는데요. 각각 언제 사용하면 좋을 지에 대한 생각을 공유해주세요.
    • 일단 useState와 useRef의 가장 큰 차이점은 상태가 변경될 때마다 리렌더링이 되는지, 안 되는지이기 때문에, input을 사용한다고 가정한다면 input창에 입력이 될 때마다 리렌더링이 되어야하는 경우 useState를 사용하는 것이 좋을 것 같고, 그게 아니라 일단 input을 입력하고 버튼을 클릭하거나 하면 기능이 동작하는 경우에는 꼭 리렌더링이 입력할 때마다 될 필요는 없기 때문에 useRef를 사용하는 것이 적절할 것 같습니다.

🍳 내일 할 일

  • 리액트 숙련 체크리스트
profile
웹 프론트엔드 개발자

0개의 댓글