TIL_2023_10_16

이종현·2023년 10월 17일
0

Today_I_Learned

목록 보기
105/145
post-thumbnail

Today 요약

  1. 가계부 프로젝트

1. What I did?

1.1 가계부 프로젝트

오늘은 주로 필터 기능 관련해서 구현했다. 어제까지는 form 데이터를 받아서 리스트에 렌더링 시키는 부분이랑 메모 부분 그리고 재구매의사를 체크하는 부분까지 진행했다.

그래서 오늘은 필터 기능 구현만 마무리하면 되기 때문에 최대한 프로젝트에만 집중하고 강의는 뒤로 미뤄두었다.

일단 대부분의 기능들, 특히 아이템의 리스트를 관리하는 배열을 고차함수로 변경해야되는 필터나 정렬 등은 가장 상위 컴포넌트에서 보통 처리한다. 그 다음 처리한 함수를 하위 컴포넌트의 prop으로 전달해서 원하는 DOM에 직접 이벤트를 전달해서 처리했다.

사실 이 부분을 나중에는 contextAPI나 Redux같은 상태관리 라이브러리를 사용해서 해결하겠지만, 지금 당장은 prop으로 전달하는 부분을 제대로 이해하기 위해 계속 drilling해서 처리하는 것도 괜찮다고 생각한다.

아무튼 이번 필터기능을 구현하는데는 7시간 반 정도 걸린 것 같다. prop으로 전달하는 부분은 잘 해내고 있는데, 아무래도 어떤 기능의 알고리즘을 생각해내는 게 힘든 것 같다. 이 부분이 나한테 많이 부족한 부분이라고 생각하기 때문에 정말로 나도 꾸준하게 코테 1문제씩 푸는 연습을 꾸준히 해야할 것 같다.

그래서 구현하는 시간을 단축하지 못했다.

필터 기능 관련된 부분에 대한 코드만 몇 가지 보자면…. 일단 아이템의 유형별 필터를 위해서 아래와 같이 구현했다.

유형별 필터

let filteredItems = itemList.filter((item) => {
  if (type === 'all') {
    return true
  }
  return item.type === type
})

타입이 전체(all)일 때는 모든 아이템을 보여주고, 나머지 경우에는 하위 컴포넌트에 전달한 함수를 통해 받아오는 type을 useState로 상태관리하고 그걸 위에 있는 필터 로직에 전달해서 전달받은 type과 item.type이 같은 경우만 필터링 할 수 있도록 했다.

const typeChangeHandler = (selectedType) => {
	setType(selectedType);
	return type;
};

가격순, 등록순 필터

그 다음은 높은 가격순, 낮은 가격 순, 최근 순, 오래된 순으로 정렬하는 부분이다.

const filterHandler = (filter) => {
  if (filter === 'high-price') {
    itemList.sort((a, b) => b.price - a.price)
    setItemList([...itemList])
  } else if (filter === 'low-price') {
    itemList.sort((a, b) => a.price - b.price)
    setItemList([...itemList])
  } else if (filter === 'latest') {
    itemList.sort((a, b) => b.order - a.order)
    setItemList([...itemList])
  } else if (filter === 'old') {
    itemList.sort((a, b) => a.order - b.order)
    setItemList([...itemList])
  }
}

이 부분은 가격은 비교적 쉽게 해결했지만, 등록된 순서를 나타내는 속성을 기존에 정의하고 있지 않았기 때문에 그 부분을 새롭게 전달하는 데 시간이 오래 걸렸다.

시작 날짜와 끝나는 날짜 사이에 있는 날짜만 필터

useEffect(() => {
  filteredItems = JSON.parse(localStorage.getItem('itemList'))
  const filteredByDate = filteredItems.filter((item) => {
    if (startDate && endDate) {
      const itemDate = new Date(item.date)
      const startDateValue = new Date(startDate)
      const endDateValue = new Date(endDate)
      return itemDate >= startDateValue && itemDate <= endDateValue
    }
    return true
  })
  setItemList(filteredByDate)
}, [startDate, endDate])

그 다음은 날짜 사이에 있는 부분만 필터하는 기능이다. 처음에는 시작 날짜만 클릭하면 그 이후 날짜를 가지고 있는 모든 리스트를 끝나는 날짜만 클릭하면 그 이전 날짜를 모두 가지고 오게 하려고 했으나, 거기까지는 내 머리의 한계가 있어서, 일단 시작 날짜와 끝나는 날짜를 모두 선택했을 때 해당 리스트를 가져올 수 있도록 구현했다.

그렇게 비교하는 모든 날짜를 Date 객체로 변환해서 비교할 수 있도록 했다. 기본적으로 날짜를 선택하지 않으면 모든 리스트를 가지고 오고 날짜를 선택하면 시작 날짜와 끝나는 날짜의 사이에 있는 리스트를 필터링 할 수 있도록 구현했다. 그리고 날짜를 클릭할 때마다 새로운 리스트를 다시 렌더링 해야 되는데 useEffect를 사용하지 않고 할 수 있는 방법이 생각나지 않아서 일단 useEffect의 의존성 배열에 시작날짜와 끝나는 날짜를 전달해서 날짜를 선택하는 걸로 날짜를 필터링해서 가져올 수 있도록 구현했다.

이렇게 구현하면서 자잘한 오류들이 많았는데, 이번에도 그런 부분을 기록하지 못하고 구현하는 데만 집중했던 게 너무 아쉽다. 매번 하는 실수인데 왜 잘 안 고쳐지는 지 모르겠다;; 오류를 기록하고 발표하는 스터디를 하나 만들어야 되나? 그래야 하려나 싶다..


profile
데이터리터러시를 중요하게 생각하는 프론트엔드 개발자

0개의 댓글