Skip to content

Commit

Permalink
Merge pull request #17 from pre-onboarding-frontend-7-team-3/develop/…
Browse files Browse the repository at this point in the history
…yeonghun

[ Fix ] http 이름
  • Loading branch information
YeonghunKO authored Nov 12, 2022
2 parents 8a1e666 + b85a2b3 commit d3353c9
Show file tree
Hide file tree
Showing 9 changed files with 47 additions and 47 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ $ git clone https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7
$ npm install
$ chmod ug+x .husky/*
```

- API 서버 실행

```
$ npm run serve-json
```

- 별도 터미널에서 Client 실행

```
$ npm start
```
Expand Down Expand Up @@ -63,49 +67,49 @@ $ npm start
- 서버에 대한 API 호출 최적화를 위해 응답으로 받은 데이터는 `캐싱` 처리하고 비동기 호출 횟수의 단축을 위해 `디바운싱` 처리했습니다.
- [ ] 2-1. API 호출별로 로컬 캐싱

- [ ] 클라이언트에서 디바운싱 시간을 이탈하여 API 호출을 이룰 때마다, 트라이(Trie) 자료구조 형식으로 캐시 스토리지에 데이터를 저장합니다.
- [ ] 클라이언트에서 디바운싱 시간을 이탈하여 API 호출을 이룰 때마다, 트라이(Trie) 자료구조 형식으로 캐시 스토리지에 데이터를 저장합니다.

- [ ] 후에 클라이언트에서 다시 API 호출을 하기 전, 서버로 보낼 `쿼리 스트링`을 캐시 스토리지에 저장된 `캐시 object key`를 비교하여 일치하는 캐시 데이터의 필요 부분을 추출하여 관련 검색어를 출력하였고, 일치하지 않을 때(캐시 처리된 데이터가 없는 경우) 서버에 다시 API 요청을 보내는 방식으로 구현했습니다.

![ezgif com-gif-maker (2)](https://user-images.githubusercontent.com/78708082/201212899-eddd696f-0d69-4566-b4a4-ceed37a8050f.gif)

https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7th-3-1-3/blob/845e8d7d4424fdddabc1f67207840e7993020bbf/src/hooks/useSearch.ts#L23-L43

<br/>

- [ ] 2-2. API 호출 횟수 최적화

- [ ] 검색창에 검색어를 입력했을 때 onChange 이벤트가 발생할 때마다 서버에 GET 요청을 보내는 것은 비효율적인 프로세스라고 공통된 의견을 나누었습니다.
- [ ] 따라서 첫 onChange 이벤트의 발생 시점으로부터 의도적인 `지연시간`을 두어 API 호출 횟수를 줄였습니다.
- [ ] 검색창에 검색어를 입력했을 때 onChange 이벤트가 발생할 때마다 서버에 GET 요청을 보내는 것은 비효율적인 프로세스라고 공통된 의견을 나누었습니다.

- [ ] 따라서 첫 onChange 이벤트의 발생 시점으로부터 의도적인 `지연시간`을 두어 API 호출 횟수를 줄였습니다.

- [ ] 검색창의 onChange 이벤트가 비동기적으로 input의 상태 값을 업데이트하되, 사용자가 입력한 검색 결과에 대한 비동기 요청은 `디바운싱 함수`에서 설정한 시간(600ms)이 지난 뒤에 최종적으로 업데이트된 상태 값을 쿼리 스트링으로 보내 호출되게 구현했습니다.

![3-1 디바운싱 후](https://user-images.githubusercontent.com/78708082/201217822-64ce8a7a-596e-4a65-9001-6bb85ce7e553.gif)

![3-1 디바운싱 전](https://user-images.githubusercontent.com/78708082/201217815-904a2ec5-822f-4ea1-9b48-677428121ed0.gif)
https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7th-3-1-3/blob/845e8d7d4424fdddabc1f67207840e7993020bbf/src/hooks/useDebounce.ts#L1-L19

https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7th-3-1-3/blob/845e8d7d4424fdddabc1f67207840e7993020bbf/src/hooks/useDebounce.ts#L1-L19

<br/>

### 3. 키보드만으로 추천 검색어들로 이동 가능한 UX 구축

- [ ] 사용자가 추천 검색어 간 `키 이벤트`(ArrowUp, ArrowDown)로 자유롭게 이동할 수 있게 구현했습니다.
- [ ] 사용자가 추천 검색어 간 `키 이벤트`(ArrowUp, ArrowDown)로 자유롭게 이동할 수 있게 구현했습니다.

- [ ] 검색창 이동 간 선택된 검색어는 하이라이트 처리로 UI를 구성했고 검색 목록 하단에 도달했을 때 ArrowUp, ArrowDown 이벤트에는 자동으로 목록 내 검색어 위치로 따라가도록 구현했습니다.

- [ ] 일반적인 사용자 검색 유형을 고려하여 페이지를 다시 돌아오거나 새로고침 했을 시에도 최근 검색어가 유지되도록 구현하였습니다. onKeyDown 이벤트가 발생했을 때 호출되는 함수는 커스텀 훅으로 분리하여 뷰 단에서의 로직을 최소화하고자 노력했습니다.

![3-1 스크롤](https://user-images.githubusercontent.com/78708082/201228395-ac315854-cc85-4a11-82d2-1cb974e662c0.gif)
https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7th-3-1-3/blob/845e8d7d4424fdddabc1f67207840e7993020bbf/src/hooks/useKeyDown.ts#L1-L58

https://github.com/pre-onboarding-frontend-7-team-3/pre-onboarding-7th-3-1-3/blob/845e8d7d4424fdddabc1f67207840e7993020bbf/src/hooks/useKeyDown.ts#L1-L58

<br/>

### 4. 객체지향형 프로그래밍

- [ ] live share로 코드 리뷰 중 재사용성이 높고 독립적으로 반복하는 코드에 대한 리팩토링이 필요하다는 의견을 공유했습니다.
- [ ] live share로 코드 리뷰 중 재사용성이 높고 독립적으로 반복하는 코드에 대한 리팩토링이 필요하다는 의견을 공유했습니다.

- [ ] 컴포넌트(모듈, 유틸리티 함수, React 컴포넌트 등) 간 직접적인 의존성을 낮추고, 둘 다 공통된 추상화에 의존해야 한다는 `의존성 역전 원칙`을 적용하고자 API 통신 함수에 적용했습니다.

Expand Down Expand Up @@ -165,7 +169,7 @@ $ npm start
│ │ ├─ SearchDiseaseService.ts // axios를 통한 기본적인 API 호출
│ │ ├─ getDataAndRegisterCache.ts // fetch를 통해 cache storage에 저장
│ │ ├─ index.ts
│  │  └─ request.ts // axios baseurl
│  │  └─ request.ts // axios baseurl
│  ├─ components
│  │  ├─ Header.tsx
│  │  ├─ Layout
Expand Down Expand Up @@ -216,10 +220,10 @@ $ npm start

## 👨‍👩‍👧‍👦 팀원

| 고영훈<br/>(팀장) | 조은지<br/>(팀원) | 김창희<br/>(팀원) | 박정민<br/>(팀원) |
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 고영훈<br/>(팀장) | 조은지<br/>(팀원) | 김창희<br/>(팀원) | 박정민<br/>(팀원) |
| --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| <img src="https://avatars.githubusercontent.com/u/65995664?s=96&v=4" alt="YeonghunKO" width="100" height="100"> | <img src="https://avatars.githubusercontent.com/u/95282989?s=96&v=4" alt="Joeunji0119" width="100" height="100"> | <img src="https://avatars.githubusercontent.com/u/45018724?s=96&v=4" alt="PiperChang" width="100" height="100"> | <img src="https://avatars.githubusercontent.com/u/55550034?s=96&v=4" alt="ono212" width="100" height="100"> |
| [YeonghunKO](https://github.com/YeonghunKO) | [Joeunji0119](https://github.com/Joeunji0119) | [PiperChang](https://github.com/PiperChang) | [ono212](https://github.com/ono212) |
| [YeonghunKO](https://github.com/YeonghunKO) | [Joeunji0119](https://github.com/Joeunji0119) | [PiperChang](https://github.com/PiperChang) | [ono212](https://github.com/ono212) |

| 문지원<br/>(팀원) | 이상민<br/>(공지) | 이지원<br/>(팀원) | 조수진<br/>(팀원) |
| ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
Expand Down
6 changes: 2 additions & 4 deletions src/apis/SearchDiseaseService.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { AxiosResponse } from "axios";

interface SearchDiseaseService {
get(url: string): Promise<AxiosResponse>;
search(keyword: string): Promise<AxiosResponse>;
get(url: string): Promise<any>;
search(keyword: string): Promise<any>;
}

export class SearchDiseaseServiceImp implements SearchDiseaseService {
Expand Down
28 changes: 14 additions & 14 deletions src/apis/getDataAndRegisterCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ import { searchDiseaseService } from ".";
import type { ResultData } from "../store/searchResult";

const getDataAndRegisterCache = (searchTarget: string): Promise<ResultData[]> => {
return searchDiseaseService.search(searchTarget).then((fetchRes) => {
let responseClone = fetchRes.clone();
caches.open("search").then((cache) => {
cache.put(
`${process.env.REACT_APP_SERVER_URL}/sick?sickNm_like=${searchTarget}`,
responseClone
);
});

// eslint-disable-next-line no-console
console.info("calling api");

return fetchRes.json();
});
return searchDiseaseService
.search(searchTarget) //
.then((fetchRes) => {
let responseClone = fetchRes.clone();
caches.open("search").then((cache) => {
cache.put(
`${process.env.REACT_APP_SERVER_URL}/sick?sickNm_like=${searchTarget}`,
responseClone
);
});
return fetchRes.json();
})
.catch((err) => console.error(err))
.finally(() => console.info("calling api"));
};

export default getDataAndRegisterCache;
4 changes: 2 additions & 2 deletions src/apis/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SearchDiseaseServiceImp } from "./SearchDiseaseService";
import { AxiosHttpClient } from "./request";
import { HttpClient } from "./request";

const httpClient = new AxiosHttpClient(`${process.env.REACT_APP_SERVER_URL}`);
const httpClient = new HttpClient(`${process.env.REACT_APP_SERVER_URL}`);
export const searchDiseaseService = new SearchDiseaseServiceImp(httpClient);
2 changes: 1 addition & 1 deletion src/apis/request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export class AxiosHttpClient {
export class HttpClient {
private baseURL: string;

constructor(baseURL: string) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Main/SearchForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const SearchForm = () => {
[diseaseListData]
);

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
const handleSubmit = (_e: React.FormEvent<HTMLFormElement>) => {
setRecentSearch(selectedResultValue || searchInputValue);
};

Expand Down
4 changes: 2 additions & 2 deletions src/components/Main/SearchItemList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { searchValue } from "../../store/searchValue";
import RecentSearchWord from "./RecentSearchWord";
import RecommendWord from "./RecommendWord";
import SearchItem from "./SearchItem";
import useSearch from "hooks/useSearch";
import useFetch from "hooks/useFetch";

const SearchItemList = () => {
const searchInputValue = useRecoilValue(searchValue);
const diseaseListData = useSearch();
const diseaseListData = useFetch();

return (
<ListWrapper>
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/useSearch.ts → src/hooks/useFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import makeTrieBySearchWord from "utils/makeTrieBySearchWord";
import getCachedData from "utils/getCachedData";
import filterCachedData from "utils/filterCachedData";

const useSearch = () => {
const useFetch = () => {
const searchInputValue = useRecoilValue(searchValue);
const [diseaseListData, setDiseaseListData] = useRecoilState<ResultData[]>(searchResultState);

Expand Down Expand Up @@ -49,4 +49,4 @@ const useSearch = () => {
return diseaseListData;
};

export default useSearch;
export default useFetch;
2 changes: 0 additions & 2 deletions src/store/searchWord.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import { atom } from "recoil";

export const recommendationList: Array<string> = ["B형간염", "비만", "관절염", "우울증", "식도염"];

0 comments on commit d3353c9

Please sign in to comment.