TS react 주요 특징 정리

ruddms936·2021년 1월 2일
0

React

목록 보기
8/8

Hi

모던한 js문법과 react를 ts로 사용하기 위한 문법을 정리하는 챕터입니다.

퍼포먼스를 위한 핵심 디자인 패턴

  1. 불변성을 유지하여 빠른 렌더링을 유도합니다.
  2. 반복되는 변수(컴포넌트), 함수(커스텀 hook, dispatch)는 useMemouseCallback를 이용하여 캐싱하도록 합니다. (메모이제이션)
  3. react 개발자 도구를 통해 렌더링 부분을 찾아 최적화 하도록 합니다.
  4. 필요에 따라 context를 분리하도록 합니다. 만약 하나의 context에 state와 dispatch를 같이 사용하면 불필요한 렌더링이 발생할 수 있습니다.
  5. component를 잘게 분리하는게 좋을수도 있습니다. 부분적인 렌더링을 하도록 유도할 수 있습니다.
  6. redux 사용시 state를 한번에 받아오는 형태가 아닌 필요한 부분만 useSelector 사용하면 변하는 값만 catch하여 렌더링 할 수 있습니다. 전체 state를 가져오게 되면 굉장히 큰 범주내에서 렌더링을 시도 할 것입니다. 혹은 shallowEqual라는 react-redux에 내장되어있는 함수사용하는것이 코드를 편리하게 작성할 수 있을꺼 같습니다. (비록 최상위 값만 비교하지만)

props

  • React.FC 혹은 type를 정의하는거 모두 상관없지만 하지만 미래적으로 React.FC 변경될 것을 대비 혹은 직관적인 코드를 위해 type을 정하는 방법이 좋을 수도 있습니다.

hooks

  • useState에 넣는 값은 알아서 타입 추론되서 들어갑니다.
    • 하지만 상태가 null일 수도 있고 아닐수도 있을때 혹은 까다로운 구조를 가진 객체이거나 배열일 때는 Generics 를 명시하는 것이 좋습니다.
  • 어떤 타입인지 모르겠다면 일단 any으로 작성 후 어떤 값이 들어오는지 인텔리센스 기능을 이용하여 확인하도록 합니다.
  • 리듀서를 만들 땐 이렇게 파라미터로 받아오는 상태의 타입과 함수가 리턴하는 타입을 동일하게 하는 것이 매우 중요합니다.
  • Ref에서 current 안의 값을 사용 하려면 null 체킹을 해주어야 합니다. 이때 ? 을 이용한 null check를 하면 문법이 깔끔합니다.

context

  • 필요에 따라 context를 분리하기
    • 만약 하나의 context에 state와 dispatch를 같이 사용하면 불필요한 렌더링이 발생할 수 있습니다.
  • Dispatch에 Generic으로 액션들의 타입을 넣어주면 추후 컴포넌트에서 액션을 디스패치 할 때 액션들에 대한 타입을 검사 할 수 있습니다.
  • undefined 체크와 같은 공통적인 로직은 커스텀 hook으로 빼서 사용하는게 효율적입니다.
  • 선언한 component 안으로(<~> </~>) 들어가는 component는 children으로 치환됩니다.
  • conText의 hook의 사용으로 생기는 장점은 Consumer을 위해 한 번 더 래핑 하지 않고 사용 가능합니다.
  • <li className={`TodoItem ${todo.done ? 'done' : ''}`}> 이용하여 값에 따라 css의 class를 select 할 수 있습니다.
  • 데이터 가공 메소드
    1. concat: 기존 배열에 합쳐서 새 배열을 반환
    2. filter: 필요한 데이터만 찾아서 반환

redux

추가적으로 필요한 의존성을 설치합니다.

yarn add redux react-redux @types/react-redux

redux의 경우엔 자체적으로 TypeScript 지원이 됩니다. 하지만 react-redux의 경우 그렇지 않기 때문에 패키지명 앞에 @types를 붙인 패키지를 설치해주어야 합니다.

  • Ducks 패턴으로 작성하여 액션 타입, 액션 생성 함수, 리듀서를 하나의 파일에 작성합니다. (파일은 tsx가 아닌 ts 입니다)
  • 액션타입은 ~ as const으로 타입 단언을 통해서 string 형태가 아닌 실제 값을 가르키도록 합니다.
    • const이기 때문에 type을 string이 아닌 지정한 값 자체로 설정하는 방법입니다.
  • 화살표 함수를 사용하면 return을 생략할 수 있어서 깔끔합니다.
  • 액션 생성 함수에 payload를 사용하는 이유는 FSA(Flux Standard Action) 규칙을 사용하기 위함 입니다.
  • ReturnType은 함수에서 반환하는 타입을 가져올 수 있게 해주는 유틸 타입입니다.
    // type 정의
    addTodo = PayloadAction<'todos/ADD_TODO', string>
    // type 하드코딩
    (text: string) => PayloadAction<'todos/ADD_TODO', string>
    // ReturnType 사용
    (text: string) => ReturnType<typeof addTodo>
    위에 2개 모두 동일합니다. ReturnType를 사용해서 addTodo type값을 알아서 가져옵니다.
  • 리듀서 작성시 함수의 반환 타입에 상태의 타입을 넣는 것을 잊지 마세요. 이를 통하여 사소한 실수를 방지 할 수 있습니다.
  • 루트 리듀서 export 할땐 스토어에서 상태 조회를 위해 useSelector사용할 때 필요하여 리듀서의 타입을 만들어서 내보내야합니다.
  • 커스텀 hook으로 인하여 굳이 HOC방식을 사용하지 않아도 됩니다.
  • 커스텀 hook 작성시 useCallback를 이용하여 dispatch function 1회 할당하도록 합니다.
  • useCallback에서 () => 은 정말 콜백에 의미이고 액션함수에 필요한 파라미터는 ()에 들어가지 않습니다.

typesafe-actions

typesafe-actions을 이용하여 쉽게 리덕스 모듈을 작성할 수 있도록 합니다.

yarn add typesafe-actions
  • 액션 생성 함수를 쉽게 만들 수 있습니다. 그동안 필수 프로퍼티인 type를 작성하는 귀찮음이 줄어듭니다.
  • 액션 타입의 유니온 작업을 쉽게 만들 수 있습니다.
  • 리듀서를 switch문이 아닌 방법으로 쉽게 작성할 수 있습니다.
    • Object map형태와 메소드 체이닝 방법이 있습니다.
    • 메소드 체이닝의 장점은 첫번째 파라미터에 액션 타입 외에도, 액션 생성 함수를 넣어서 액션 타입을 선언할 필요가 줄어듭니다. 액션 타입과 액션 생성 함수는 1:1 맵핑 이기 때문에 메소드 체이닝 방법이 효율적이라고 생각됩니다.

액션 생성 함수 예제 코드

interface kakaoFriend {
  id: number;
  group: string;
  list: {
    name: string;
  }[];
}

const lookupKakaoFriend = createAction('kakao/lookupFriend', ({ id, group, list }: kakaoFriend) => ({
  id,
  group,
  list,
}))();

console.log(lookupKakaoFriend({ id: 2132, group: '학교', list: [{ name: '박경은1' }, { name: '박경은2' }] }));

액션의 페이로드로 들어가는 값은 Generic을 사용하여 정해줄 수 있으며, 만약 액션의 페이로드에 아무것도 필요 없다면 Generic을 생략하시면 됩니다.

컨벤션

  • 디렉토리: 복수의 경우s
  • component: 파일명 파스칼, 함수명도 파스칼로 동일
  • reducer: 파일명 카멜
  • 커스텀 hook: use~

배포

  • CRA를 yarn build 하더라도 정상적으로 불러오지 못할 수 있습니다.
  • React build시 sourcemap 제거해야합니다. 디버깅 도구로 source code가 노출되기 때문입니다.
profile
"꼬꼬마 개발자" 공부 중인 내용은 앞으로 개인 notion 작성 중입니다.

0개의 댓글