영양제에 관한 많은 데이터를 어떤 방식으로 처리할 것인지 팀원들과 개발 시작전에 논의를 나누었다.
onChange 이벤트에 따른 데이터 fetch 방식 논의
- state에 모든 API Data를 담아둔 뒤 match 결과를 맵핑한다.❌
- onChange마다 해당 값에 맞는 데이터를 DB로부터
get 요청을 보낸다. ✅
1번의 경우
state 배열 내에서 빠르게 match값들을 찾아 리스팅해줄 수 있으며 데이터 정렬 횟수를 최소화 할 수 있다.
그러나 만약 API데이터의 크기가 클 경우, 초기 데이터 fetch에 따른 로딩 시간이
굉장히 길어질 수 있으며메모리를 너무 방대하게 차지하는
공간 비효율성이 초래될 수 있다.
2번의 경우
데이터 fetch 로딩 및 렌더링 시간을 단축하며 메모리 공간을 크게 차지하지 않아도 되지만, onChange이벤트는 너무 잦은 이벤트를 야기하기 때문에 서버에 너무 많은 요청이 일어나 서버에 과부하가 발생할 수 있고, 서버에서 응답 받은 데이터를 매 응답마다 정렬해줘야 한다.
추후 확장 가능성을 고려했을 때 효율적이지 못한 방식이 될 것이라 판단하여 2번 방식을 활용하기로 결정했다.
잦은 요청과 그에 따른 데이터 처리량의 부하를 예방하기 위하여, 매 요청마다 모든 일치 데이터를 불러오는 것이 아닌, 상위 20개씩의 데이터만 우선적으로 불러와 이후의 데이터 페칭은 ‘무한스크롤'방식을 통해 불러와지도록 기능설계를 했다. 이러한 데이터 간의 우선순위를 매기기 위해 임의로 registCount라는 필드를 DB에 추가했고, 고객이 가장 많이 담은 순서대로 데이터가 먼저 불러와지도록 유도했다.
- 검색창, 반응형, Header & Footer
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;
<SearchContainer>
<SearchForm inputValue={inputValue} handleChange={handleChange} />
<SearchResult
list={results}
setResults={setResults}
inputValue={inputValue}
range={range}
setRange={setRange}
/>
</SearchContainer>
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})`,
};
![]()
이번 프로젝트는 다른 프로젝트와는 다르게 시작에 앞서 더 많은 토론을 팀원들과 나누었고 로직의 간결성뿐만 아니라 데이터의 효율적인 처리 과정에 대해서도 다양한 방법으로 토론할 수 있었다. 어느새 프리온보딩 코스 과정이 절반을 넘어가고 있다. 코스 시작 전의 나와 지금의 나는 정말 많이 변했고 성장했다고 생각한다. 아직 끝나지 않았으니, 마지막까지 나를 성장시키는 멋진 시간을 보내고 싶다.🌠