[프로젝트 회고] 영양제 검색 페이지

윤창현·2022년 2월 21일
1

Project-Log

목록 보기
16/17
post-thumbnail

💊 영양제 검색 페이지

📝 과제 설명

  • 페이지 설계와 로직의 고민, 해결 과정에 중점을 두었던 과제.
  • 사용자가 검색한 키워드가 포함된 영양제 목록을 불러와 화면에 출력하는
    무한스크롤을 통해 보여주는 페이지.

⚙️ 기술 스택

  • React, Next.js
  • TypeScript, JavaScript, Styled-Component
  • Git & GitHub, Build Tool (Create Next App)

⌚️ 설계 과정

  • 영양제에 관한 많은 데이터를 어떤 방식으로 처리할 것인지 팀원들과 개발 시작전에 논의를 나누었다.

    onChange 이벤트에 따른 데이터 fetch 방식 논의

      1. state에 모든 API Data를 담아둔 뒤 match 결과를 맵핑한다.❌
      1. onChange마다 해당 값에 맞는 데이터를 DB로부터
        get 요청을 보낸다. ✅
  • 1번의 경우
    state 배열 내에서 빠르게 match값들을 찾아 리스팅해줄 수 있으며 데이터 정렬 횟수를 최소화 할 수 있다.
    그러나 만약 API데이터의 크기가 클 경우, 초기 데이터 fetch에 따른 로딩 시간이
    굉장히 길어질 수 있으며메모리를 너무 방대하게 차지하는
    공간 비효율성이 초래될 수 있다.

  • 2번의 경우
    데이터 fetch 로딩 및 렌더링 시간을 단축하며 메모리 공간을 크게 차지하지 않아도 되지만, onChange이벤트는 너무 잦은 이벤트를 야기하기 때문에 서버에 너무 많은 요청이 일어나 서버에 과부하가 발생할 수 있고, 서버에서 응답 받은 데이터를 매 응답마다 정렬해줘야 한다.

추후 확장 가능성을 고려했을 때 효율적이지 못한 방식이 될 것이라 판단하여 2번 방식을 활용하기로 결정했다.

잦은 요청과 그에 따른 데이터 처리량의 부하를 예방하기 위하여, 매 요청마다 모든 일치 데이터를 불러오는 것이 아닌, 상위 20개씩의 데이터만 우선적으로 불러와 이후의 데이터 페칭은 ‘무한스크롤'방식을 통해 불러와지도록 기능설계를 했다. 이러한 데이터 간의 우선순위를 매기기 위해 임의로 registCount라는 필드를 DB에 추가했고, 고객이 가장 많이 담은 순서대로 데이터가 먼저 불러와지도록 유도했다.


💻 기능 구현

  • 검색창, 반응형, Header & Footer

⌨️ 검색창

  • 최초에는 검색창을 담당하는 SearchSection이라는 컴포넌트에서
    로직을 구현하였으나 리팩토링 과정에서 api에 필터링 코드를 병합하여,
    api 내에서 정렬과 필터를 구현 후 컴포넌트로 전달할 수 있도록 바꾸었다.
   const { requests: result } = JSON.parse(JSON.stringify(db));
  const sortedResult = mergeSort(result);
  const {
    query: { length, text },
  } = req;
  const lengthNum = Number(length);
  const filteredList = sortedResult.filter((item: DataTypes) => {
    const regex = new RegExp(`${text}`, 'gi');
    const filterName = item.name.match(regex);
    const filterBrand = item.brand.match(regex);
    return filterName || filterBrand;
  });
  const slicedResult = filteredList.slice(0, lengthNum);
  res.status(200).json({ requests: JSON.parse(JSON.stringify(slicedResult)) });
  return;
  • 그 후에 상위 컴포넌트에서 데이터를 받아오는 함수를 작성 후, 검색 input과 검색 결과 창에 props로 검색input에 들어가는 value 값, 검색 값을 validation하는 정규표현식, 등을 보내주었다.
   <SearchContainer>
      <SearchForm inputValue={inputValue} handleChange={handleChange} />
      <SearchResult
        list={results}
        setResults={setResults}
        inputValue={inputValue}
        range={range}
        setRange={setRange}
      />
    </SearchContainer>

  • constants폴더 index.ts파일에 아래와 같은 로직을 Header & Footer 등에 가져와서 사용할 수 있게 작성하였다.
  • MEDIUM일 때 header & footer 우측 메뉴 부분과 각 글자 위치에 변동을 주었고
  • SMALL은 휴대폰 화면을 기준으로 간결하게 레이아웃 구성을 바꾸었다.
const SIZE = {
  SMALL: '800px',
  MEDIUM: '1200px',
  LARGE: '1400px',
};

export const DEVICE = {
  SMALL: `(max-width: ${SIZE.SMALL})`,
  MEDIUM: `(max-width: ${SIZE.MEDIUM})`,
  LARGE: `(max-width: ${SIZE.LARGE})`,
};

🌅 최종 구현

이번 프로젝트는 다른 프로젝트와는 다르게 시작에 앞서 더 많은 토론을 팀원들과 나누었고 로직의 간결성뿐만 아니라 데이터의 효율적인 처리 과정에 대해서도 다양한 방법으로 토론할 수 있었다. 어느새 프리온보딩 코스 과정이 절반을 넘어가고 있다. 코스 시작 전의 나와 지금의 나는 정말 많이 변했고 성장했다고 생각한다. 아직 끝나지 않았으니, 마지막까지 나를 성장시키는 멋진 시간을 보내고 싶다.🌠

profile
긍정적 영향을 전하며 함께하고 싶은 개발자를 그린다.

0개의 댓글