Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[조은주] 기능구현 챌린지 #3

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

dmswn1004
Copy link

@dmswn1004 dmswn1004 commented May 10, 2024

필수 구현 사항

  • 질환 명 검색시 API를 호출하여 드롭박스를 통해 추천 검색어를 보여주는 기능을 구현합니다.
    • 검색어가 없을 시 “검색어 없음” 표출
    • 최근에 검색어를 보여줍니다.
  • 검색어를 검색 시 결과를 리스트로 보여줍니다.
    • 검색어가 없을 시 화면도 구현
    • 검색 결과 컴포넌트를 클릭 시 https://clinicaltrialskorea.com/studies/{검색어ID} 링크로 이동
  • 입력마다 API 호출하지 않도록 API 호출 횟수를 줄이는 전략 수립 및 실행
    • 검색어 입력 시 500ms마다 요청이 되도록 간단한 디바운스 적용
    • useQuery에 enabled을 사용해 조건에 맞을 경우에만 실행하도록 구현
  • API를 호출할 때 마다 console.info("calling api") 출력을 통해 콘솔창에서 API 호출 횟수 확인이 가능하도록 설정

추가 구현 사항

  • 공통 컴포넌트 구현
    • 헤더 구현
    • 검색 리스트 구현
    • 드롭박스 구현
    • 모달 구현
  • 커스텀훅 사용을 통한 로직 분리

선택 구현 사항

  • [선택 사항 1] 키보드만으로 추천 검색어들로 이동 가능하도록 구현합니다.
    • ex) 키보드 방향키, 탭을 사용하여 다음 추천 검색어로 이동
  • [선택 사항 2] React-Query를 활용하여 캐싱을 구현합니다.
  • [선택 사항 3] 검색어 결과는 페이지네이션 또는 무한스크롤 선택합니다.
    • 외부 라이브러리 없이 구현할 경우 추가 점수
  • [선택 사항 4] 스크랩 저장 기능을 구현합니다.
    • 페이지를 새로고침 해도 리스트가 남아있도록 구현.
    • 즐겨찾기 페이지에서 스크랩한 결과물 리스트 보여주도록 구현.
    • 확인 모달을 통해 스크랩을 삭제.
  • [선택 사항 5] 뷰포트 크기에 따른 반응형 UI를 구현합니다.
  • [선택 사항 6] Storybook을 사용하여 UI 인터렉션 테스팅을 구현합니다.

과제를 수행하면서 진행하셨던 고민

  • 스토리지에 데이터 저장 시 리렌더링 문제

구현하고자 했던 설계의 방향성

  • 공통 컴포넌트를 사용하여 재사용 가능한 컴포넌트 구현

@dmswn1004 dmswn1004 self-assigned this May 10, 2024
Copy link
Member

@Leeseunghwan7305 Leeseunghwan7305 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다 !

Comment on lines 18 to 20
<a className={cx("nav-items")} href="/bookmarks">
즐겨찾기
</a>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a태그와 link태그 차이점이 있는데
Link 태그와 a 태그의 차이점을 검색해봤어요 !
이는 전체 페이지가 다시 로드되어 리액트 상태가 모두 초기화된다는 것을 말한다. 리액트를 사용할 때 a 태그를 사용하면 치명적인 가장 큰 이유가 된다. 반면 Link 태그는 클릭해도 새로고침되지 않는다.
참고해서 상황에 맞게 바꿔보시면 좋을 것 같습니다 ! 🙂

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 정보 감사해요!! 상황별로 적절하게 사용해야 겠네요!!

<div className={cx("modal-overlay")}>
<dialog open={isOpen} className={cx("modal-container")}>
<label>즐겨찾기에서 제거하시겠습니까?</label>
<menu className={cx("menu-container")}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

menu태그 새롭게 알아가요

Leeseunghwan7305 added a commit that referenced this pull request May 13, 2024
Copy link
Member

@gyeong3un2 gyeong3un2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요 은주님!
코드 보는데, 가독성 있게 작성해주셔서 이해하기 편했던 거 같아요! 😁
수고하셨습니당!! 😁


export default function DropdownItem({ searchValue, search }: DropdownItemProps) {
return (
<div className={cx("recent-item")}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classnames/bind의 경우 조건부 스타일을 줄 때 사용하는 거로 알고 있어서
조건부가 아닐 때 css를 import하시는 용도라면, css 파일에서 카멜케이스로 해서 아래와 같이 style을 가지고 사용하시는 것도 좋을 거 같아요!

import style from './index.module.scss';

<div className={style.recentItem}>
  // ...
</div>

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하,,, classnames/bind가 그냥 사용하는 것보다 조건부 스타일을 적용할 때 더 유용한 거군요! 다음부터는 잘 지켜서 사용해 봐야겠네요!! 감사합니다.☺️

children: ReactNode;
}

export default function SearchItemLayout({ children }: SearchItemLayoutProps) {
Copy link
Member

@gyeong3un2 gyeong3un2 May 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 최근에 알게 된 건데,
react에 children을 가진 props 타입이 있어서, ReactNode 대신 이걸 사용하면 코드가 좀 더 가독성 있게 바껴서 좋더라구여!
그래서 은주님도 한번 사용해보시면 좋을 거 같아요! 😁

import { PropsWithChildren } from 'react';

export default function SearchItemLayout({ children }: PropsWithChildren) {
  // ...
}

만약 다른 타입들도 있는 props라면 아래와 같이 Generic으로도 사용할 수 있어요!
그러면 children과 구분되는 것 같기도 해서 저는 유용하게 사용하고 있어서 추천드립니당!

import { PropsWithChildren } from 'react';

interface IComponentProps {
  name: string;
  content: string;
}

export default function Component({ children }: PropsWithChildren<IComponentProps>) {
  // ...
}

Copy link
Author

@dmswn1004 dmswn1004 May 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요. 경은님!

PropsWithChildren이라는 타입을 몰랐는데 이렇게 사용해도 유용할 것 같에요!! 좋은 정보 감사해요!!

그런데 PropsWithChildren에 대해 검색해 봤는데 이 타입의 경우 children이 옵셔널로 지정되어 있어 children이 존재하지 않더라도 에러가 발생하지 않는다고 해요!

이를 해결하기 위해 StrictPropsWithChildren 타입을 선언해 children이 꼭 필요한 경우 에러가 발생하도록 하는 것도 좋아 보여요!

import { ReactNode } from "react";

export type StrictPropsWithChildren<P = unknown> = P & {
  children: ReactNode;
};

이렇게 타입을 선언하면, children이 누락된 경우 에러가 발생하게 되어 코드의 안정성을 높일 수 있습니다. 좋은 정보 공유해 주셔서 감사합니다!

피드백 감사합니다! 😊

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StrictPropsWithChildren이 있었군요!
확실히 PropsWithChildren 보다는 안정성이 좋을 거 같아요!
좋은 정보 감사합니당! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants