치춘짱베리굿나이스

[프리온보딩] 220510 개인과제 #1 본문

프로젝트/원티드 프리온보딩

[프리온보딩] 220510 개인과제 #1

치춘 2022. 5. 11. 00:45

개인과제 #1

공식적인 내생각

손가락 끝을 다쳐서 반창고를 감았더니 타자치는 느낌이 이상하다

오늘 유독 기침이 심해져서 집중이 하나도 안 됐다... 그래도 개인과제 얼레벌레 시작해서 다행이다

노션 정리보다 코드 작성에 더 시간투자 많이 하니까 재미있었다 남들보단 실력이 부족할지 몰라도 내가 재밌는 개발을 할 수 있어서 다행이다

코드리뷰 1등으로 요청하길 잘했다... 로직만 중요한게 아님을 많이 느낌

작업 내용

typescript interface에서 ?의 의미

interface ITest {
    value1: string;
    value2?: string;
}

있어도 되고 없어도 되는 값을 의미한다

커스텀 훅 만들어보기

export const useFetchMovie = (page: number): ISearchResult | undefined => {
  const searchValue = useRecoilValue(searchValueState);
  const setLoading = useSetRecoilState(searchLoadingState);
  const [searchResult, setSearchResult] = useState(undefined);

  useEffect(() => {
    const fetchSearchResult = async () => {
      setLoading(true);
      try {
        const response = await getMovieData(searchValue, page);
        setSearchResult(response.data);
      } catch (error) {
        setSearchResult(undefined);
      } finally {
        setLoading(false);
      }
    };
    searchValue !== '' && fetchSearchResult();
  }, [page, searchValue, setLoading]);
  return searchResult;
};

검색창에 입력해서 submit한 값 (키워드) 을 Recoil을 이용하여 전역으로 갖고 있고, 이 값이 바뀔 때마다 axios를 통해 영화 데이터를 get 해주었다

굳이 입력값을 Recoil로 다룬 이유는 검색 결과를 출력하는 컴포넌트와 검색어를 입력하는 컴포넌트가 형제 관계라 상태값을 전달하기 번거로워서였음

그렇다고 서버에서 받은 데이터를 전역으로 관리하자니 무겁고, 전역 상태관리 안쓰고 부모 통해서 받아주자니 번거롭고.... Recoil이 러닝커브 낮다고 하는 이유를 알겠다 atom 정도는 가볍게 쓰기 좋다

finally는 리뷰를 듣고 코드중복을 줄일 겸 한번 개편해보았고, 원래는 axios 부분도 getMovieData 함수로 따로 빼지 않고 useFetchMovie 안에 넣어주었는데 urlid를 env로 빼는 김에 분리해 주었다

컴포넌트 내에서 useEffect에 여러 로직을 덕지덕지 붙일 필요 없이 훅으로 만들어서 가져다 사용하기만 하니까 너무 편리하고 재밌다..

폴더구조

무지개색이 참으로 영롱하다

hooks 폴더도 src 루트로 옮길까 고민중이다

모든 컴포넌트는 components 폴더에 정리하고, 컴포넌트를 가져다 쓰는 페이지는 pages에 정리했다

리액트를 처음 접했던 프로젝트에서 그러한 폴더 구조를 사용했어서 익숙해진 탓에 그냥 쓰기도 했고, 아토믹 디자인 같은 건 정이 잘 안 가더라

원래 폴더 안에 컴포넌트 파일이랑 index.js / index.ts 롤 분리하는 게 취향이었는데, 처음에는 index.js에 컴포넌트 관련 내용을 전부 넣고 한번에 export 하는 것이 익숙하지가 않아서 고생 깨나 했다

컴포넌트를 전부 components에 몰아넣었다간 나중에 컴포넌트가 기하급수적으로 많아지는 프로젝트에선 컴포넌트 찾아보기가 힘들어질 것 같으니 특정 페이지에서만 불러와서 사용하는 컴포넌트는 페이지 폴더로 따로 빼놔야겠다

atomsinterfaces는 폴더를 어찌 정리해야할지 모르겠어서 utils에 빼 놨는데 썩 좋은 것 같진 않다

내 코드 중간리뷰 내용

  • 포트폴리오용으론 Readme.md를 잘 쓰는 것이 좋다 (Create React App 기본값 노출되게 하지 않기)
  • router.ts 와 같이 컴포넌트가 아닌 함수들, 또는 별개의 기능들은 파일명을 소문자로 시작하도록 하자
  • 폴더 안에 파일이 하나밖에 없다면 굳이 폴더로 만들 필요가 없다
  • 여러 컴포넌트 또는 페이지에서 가져다 쓰는 컴포넌트만 components 폴더 안에 넣고, 한 페이지에서만 사용되는 컴포넌트는 각 페이지 폴더 안에 (pages/[페이지명]/[컴포넌트명] 등) 넣는 게 좋다
  • 아니면 여러 컴포넌트 / 페이지가 사용하는 컴포넌트는 components/common 폴더에 넣고, 일반 컴포넌트는 components/[컴포넌트명] 에 넣는 것도 고려해보기
  • axios 와 같은 데이터 fetching 함수는 services 폴더에 정리하기
  • 데이터 로딩을 구현할 때 useRecoil도 나쁘지 않지만 suspense 라는 리액트 자체 컴포넌트를 사용해보는 것도 좋음
  • axios를 사용할 때, url을 함수 안에 그냥 넣으면 재사용성을 해치므로 + api key 등은 보안이슈도 있으므로 변수 등으로 빼서 정리하는 것을 추천
  • NavigationBar 같이 모든 페이지에서 보여지는 컴포넌트의 경우, 라우터에 심을 때 react router의 Template 알아보기
  • try / catch 내에서 중복적으로 사용하는 코드는 finally를 사용하여 중복을 없애고 필연적으로 실행되도록 하는 것이 좋다
  • thentry / catch의 차이: 취향차이
  • and 연산자 (조건문 && 함수, 컴포넌트) 대신 if / else 사용을 추천
Comments