왜 React.FC 안쓰는가

ruddms936·2021년 1월 1일
0

React

목록 보기
7/8

Hi

js가 아닌 ts를 이용하면서 react의 문법의 이슈를 정리하는 챕터입니다.

props

React.FC or 직접 type를 정의하는 방법이 있습니다.

원래에는 React.FCdefaultProps 혹은 props.children 이슈 때문에 직접 type를 정의하는 방법이 좋다고 생각했지만 생각을 해보니 React.FC를 이용해서 충분한 우회 방법을 찾아냈습니다.

공식적인 가이드

js으로 개발된 react를 ts으로 마이그레이션을 위해 개발자가 연구를 통해 탄생한 type이 React.FC이라고 생각됩니다.

이후 발생하는 이슈도 언젠간 공식적으로 수정될 확률이 높고 안전하게 사용할 수 있습니다.

반대로 말하면 어떻게 미래에 어떤 방식으로 바뀔지 보장할 수 없는 위험이 있습니다.

짧아지는 코드

type를 정의하고 사용하면 아마 아래와 같은 코드가 나오게 됩니다.

interface MyProps {
  name: string;
  mark: string;
  optional?: string;
  onClick: (name: string) => void;
}

function Greetings({ name, mark, optional, onClick }: MyProps): JSX.Element {
}

MyProps으로 props type를 정의하고 함수의 return type까지 JSX.Element으로 정의하였습니다.

이번엔 React.FC으로 작성해보도록 하겠습니다.

interface MyProps {
  name: string;
  mark: string;
  optional?: string;
  onClick: (name: string) => void;
}

const Greetings: React.FC<MyProps> = ({ name, mark, optional, onClick }) => {
}

사실 React.FC이나 크게 차이는 없지만 React.FC는 props와 return까지 한번에 검사를 해주기 때문에 짧은 코드를 생산할 수 있습니다.

Lint을 빡세게 잡아서 모든 함수의 return까지 명시를 해야하는 rule이 있다면 React.FC은 좋은 선택일지도 모릅니다.

defaultProps

React.FC를 사용하면 .defaultProps을 작성해도 체크되지 않는 버그가 있습니다.

ES6 문법인 기본값 매개변수를 이용하여 해결할 수 있습니다.

const Greetings: React.FC<MyProps> = ({ name, mark, optional = 'Hi', onClick }) => {
}

props이름이 변경되면 파라미터의 props이름과 defaultProps이름을 2가지 모두 변경해야 하는데 한번에 함수 파라미터에서 변경하는게 더 편해보입니다.

이미 진행된 react.js에서 defaultProps를 사용했다면 react.ts으로 마이그레이션을 위해서는 다시 파라미터에 기본값을 명시해야되기 때문에 오히려 불편한 방법이 될 수 있을꺼 같습니다.

props.children

children 값이 옵셔널 형태라 사용유무를 모르겠다면 사용되는 component의 type에 명시적으로 선언해주면 됩니다.

interface MyProps {
  children: React.ReactNode;
}

js스러워서?

일부의 레퍼런스 중에서 props를 일일이 지정해주는것이 간단하고 JavaScript에 훨씬 더 가깝다고 말합니다.

명시가 직관적이고 간단하며 추후, React.FC가 변경된다고 해도 props를 받아오는 type를 명시한 것은 ts의 기능이기 때문에 하위호환성도 크게 걱정되지는 않을겁니다.

하지만 js에 가깝도록 ts에서 코딩하는 이유는 모르겠습니다. 강력한 타입의 기능을 사용하기 위해 ts를 사용해야하는데 class 기반의 React의 유물인 defaultProps를 사용해서 type을 명시한다는거 부터가 ts에서 사용하는 이유는 사라지고 있는거 같습니다.

profile
"꼬꼬마 개발자" 공부 중인 내용은 앞으로 개인 notion 작성 중입니다.

0개의 댓글