팀프로젝트 5주차 + 필터링 구현

zizi·2022년 12월 19일
0

팀프로젝트

목록 보기
5/7

202212

이번주는 백엔드에서 데이터를 받아와서 카카오 데이터와 연결, 편의점 상세페이지, 리뷰 작성/수정 페이지 구현과 지도 리스트 필터링 기능 구현을 주로 하였는데 아무래도 UI + 기능 구현이다보니 많은 것들을 하게되어 정리하기 쉽지 않을 것 같다.

첫번째 수업

첫번째 수업에서는 solid 원칙에 대해서 공부했다.
1. SRP 단일 책임의 원칙 - 하나의 컴포넌트에 너무 많은 기능을 넣지 말 것 / 최대한 다른 모듈로 분리시키기
2. OCP 개방 폐쇄 원칙 - 적절한 props 사용 / 다른 추가 사항이 일어나더라도 기존 구성은 변경하지 않으며 확장에 대한 가능성을 열어줘야 한다, 컴포넌트의 확장성을 높일 수 있음
3. LSP 리스코프 치환 원칙 - 클래스 관련 // 리액트에선 많이 상관 없음
4. ISP 인터페이스 분리 원칙 - props 필요한 부분만 전달
5. DIP 의존관계 역전 원칙 - 리덕스 툴킷에서 액션을 디스패치 하는 것(액션에 따라 받는 부분을 바꿀 수 있음)

https://bottom-to-top.tistory.com/27
https://sumini.dev/til/009-react-solid/

→ 변경이 쉽도록, 하나가 변경되면 여러 곳이 변경되면 안된다.

*피드백
-develop 브랜치로 머지하면서 package-lock.json 오류 -> 흔히 나타나는 오류로 팀원 간에 npm 버전이 달라서 그럴 수 있기 때문에 확인하고 하나로 통일해서 진행하기
-일정보다 빠르게 진행 시 할 수 있는 추가 과제들(시맨틱 태그, 접근성 향상, TDD 등)

두번째 수업

두번째 수업때는 pull request를 진행했던 브랜치들에 대해서 피드백을 받았다.
-eslint rule 추가 → exhaustive-deps-warning (중요함!)
-qs 라이브러리 이용 query String 값 배열로 보내기
-map 메소드 사용 시 idx보다는 고유한 값으로
-공통 컴포넌트 사용 시에도 최대한 반복 줄이기
-컨벤션 공부하기 -> 참고 https://github.com/naver/eslint-config-naver/blob/master/STYLE_GUIDE.md#naming-conventions

결정된 점

  • import 컨벤션 순서
  1. React
  2. Library(Package)
  3. Component
  4. 변수 / 이미지
  5. css 파일(scss 파일)
  • pn룰 도입(PR시)
  • props 컨벤션 통일 -> React.FC

공부한 점

  • useState를 props로 넘길때
selected: string[]
setSelected: (selected: string[]) => void
  • 공통 컴포넌트가 들어가는 부분에 리스트를 상수로 빼서 이를 다시 map 메소드 사용하여 반복 줄이기
const ITEMS = [
  { title: '제품', keywordArray: PRODUCT },
  { title: '분위기', keywordArray: MOOD },
  { title: '편의시설', keywordArray: FACILITIES },
]
<>
{ITEMS.map((el) => (
  <Select
  key={el.title}
  title={el.title}
  keywordArray={el.keywordArray}
  selected={selectKeyword}
  setSelected={setSelectKeyword}
  selectType={'checkbox'}/>
))}
</>
  • 편의점 리스트 필터링 구현(거리순은 아직 더 공부가 필요함)
  • edit 페이지를 write 페이지와 함께 사용하기 위해 수정 버튼 클릭 시엔 기존 리뷰 정보 가져오기

느낀 점

저번주 주말 ~ 이번주 초반에는 package-lock.json 충돌 오류로 또 머지 문제가 생겨 복잡했었는데 npm 버전을 맞추고 통일해서 하니 한번에 쉽게 해결되어서 다행이었다.

이번주는 많은 기능을 구현해야 해서 처음에는 막막하기만 했는데 그래도 팀원들과 함께 해서 할 수 있었던 것 같다. 특히 필터링 부분은 어떻게 해야할 지 고민이 많았지만 이렇게 저렇게 해보고 막히는 부분은 팀원들에게 물어보고 같이 하면서 해낼 수 있었다. 배우고 느낀 게 매우 많은 주였어서 모두 머릿 속에 꼭꼭 기억하고 싶다.

주요 부분인 메인페이지와 리뷰페이지의 기능이 거의 완료되었다!

  • 카카오에서 받아온 편의점 정보 + 우리 db의 리뷰 데이터를 붙여서 리스트에 다시 뿌려주기
  • 편의점 리스트 sort - 별점 높은순 리뷰 많은순 완료 // 거리순은 distance가 없는 경우가 있어서 아직 진행중
  • 편의점 리스트 필터링(편의점 브랜드, 리뷰의 키워드)
  • 각 편의점 별 상세페이지 / 리뷰 CRUD 구현

처음에 기획했던 것과 비슷하게 기능과 UI가 대체로 잘 나오고 있는 것 같아서 다행이었고, 팀원분의 노고로 로고까지 예쁘게 업그레이드 되었다!

기능을 어느정도 구현하고 백엔드와 붙여서 진행해보니 로그인 오류나 생각지 못했던 문제들이 생겼고 이 외에도 구현했던 부분에 약간의 오류들이 나타나서 이 부분을 수정하기도 했는데, 아마 마지막 주차에 develop 브랜치로 모두 머지하고 나면 쭉 훑으면서 수정할 부분을 정리해야 할 것 같다.


편의점 리스트 필터링 하기

우리 팀의 필터링 부분은 다음과 같고,

필터링은 브랜드, 키워드 모두 중복선택이 가능함

*브랜드
'GS25', 'CU', '세븐일레븐', '이마트24', '미니스톱', '기타'가 있고, 기타 선택 시 나머지 편의점이 아닌 곳을 가져와야해서 약간의 어려움이 있었음
-> 선택된 브랜드 없음 or 기타 + 브랜드 선택 or 브랜드 선택(기타 없음)

*키워드
키워드는 종류는 많았지만 선택된 키워드중 하나라도 리뷰에 포함되어 있으면 편의점 리스트에 띄우는 것으로 결정
-> 선택된 키워드 없음 or 키워드 선택


-FilterBox.ts
1. 편의점 브랜드 sort 함수

  const sortBrand = () => {
    let newData: ConvType[]

    if (selectBrand.length === 0) {
    // 선택된 브랜드가 없을 시 원래 편의점 리스트를 가져옴
      newData = convList
      
      // 선택된 브랜드에 기타가 포함되어 있을 시 
      // 기타 / 브랜드 이름 분리해서 결과 가져오기
    } else if (selectBrand.includes('기타')) {
    // 편의점 이름에 브랜드 이름이 있는 경우 
      newData = stores.filter((data) =>
        selectBrand.includes(data.place_name.split(' ')[0])
      )
    // 편의점 이름에 브랜드 이름이 없는 경우(기타)
      const etcData = stores.filter(
        (data) =>
          !['GS25', 'CU', '세븐일레븐', '이마트24', '미니스톱'].includes(
            data.place_name.split(' ')[0]
          )
      )
      newData = [...newData, ...etcData]
    } else {
    // 선택된 브랜드가 있고 기타는 없을 시
      newData = stores.filter((data) =>
        selectBrand.includes(data.place_name.split(' ')[0])
      )
    }
    return newData
  }

2. 키워드 sort 함수
선택된 키워드들은 배열이었고, filter 메소드 안에서 각 데이터가 문자열 배열을 하나라도 포함하고 있는 지 확인했어야 하기때문에 조금 헷갈렸는데, some 메소드를 활용하여 할 수 있었다.

  const sortKeyword = (newData: ConvType[]) => {
    let sortResult

    if (selectKeyword.length === 0) {
    // 선택된 키워드가 없을 시 원래 편의점 리스트를 가져옴
      sortResult = newData
    } else {
    // 선택된 키워드가 하나라도 리뷰에 포함되어 있으면 리스트에 포함
      sortResult = newData.filter((data) =>
        data.keywordList.some((keyword) => selectKeyword.includes(keyword))
      )
    }

    return sortResult
  }

3. 버튼 누르면 sort 진행

  const sortStore = () => {
   ...생략...
   
// 브랜드 sort 함수 진행 -> 이 데이터를 가지고 키워드 sort 함수 진행 
    const newData = sortBrand()
    const sortResult = sortKeyword(newData)

// 완료된 결과를 store에 넣어주고 지도에 표시
    dispatch(setSortStores(sortResult))
    sortCallBack(sortResult)

...생략...

현재는 필터링 부분 리팩토링까지 완료하여 코드가 조금 달라졌다.

0개의 댓글