[React] React.FC 사용 지양하기

BOZZANG·2023년 7월 5일
0

TIL

목록 보기
1/2
💡 React 18 이상에서 React.FC는 사라졌다

React.FC란?

  • Function Component의 줄임말로 React + TypeScript 조합으로 개발할 때 사용하는 타입
  • 함수형 컴포넌트 사용 시 타입 선언에 쓸 수 있도록 React에서 제공하는 타입

React.FC 사용해보기

 type UserProps = {
	name: string;
}; 

const Profile: React.FC<UserProps> = ({name}) => {
	<div> 안녕하세요, {name}<div>
);

export default Profile;

React.FC를 사용하는 경우 위와 같이 props의 타입을 Generics로 넣어서 사용한다.


React.FC 사용을 지양해야 하는 이유

우선 지난 문서이긴 하지만 CRA에서 기본 템플릿에 FC를 빼야한다는 PR이 올라왔고, 그것이 실제로 반영되었다고 한다. 그 이유는 아래와 같다.

1. children을 암시적으로 가지고 있다.

React.FC 사용 시 props는 children을 암시적으로 가지게 된다.

이는 꼭 타입스크립트에 한정하지 않더라도 안티패턴이라고 한다.

const App: React.FC = () => {
  return <div>hi</div>;
};

const Example = () => {
  <App>
    <div>Unwanted children</div>
  </App>;
};

위에서 은 컴포넌트에서 children을 다루고 있지 않음에도 Example에서 children을 넘겨주고 있으며, 이는 런타임 에러가 발생하지 않는다.

이는 FC를 사용하지 않는다면 잡아낼 수 있다.

물론 오히려 FC를 사용해서 children을 작성하지 않아도 되는 편리함이 있을 수도 있으나 타입스크립트를 사용하는 목적에 어긋난다.

2. 타입스크립트의 제네릭 문법을 지원하지 않는다.

다음과 같이 제네릭 컴포넌트를 작성한다고 예를 들어보자.

type GenericComponentProps<T> = {
  prop: T;
  callback: (t: T) => void;
};

const GenericComponent = <T>(props: GenericComponentProps<T>) => {
  /*...*/
};

그러나 이런 형태는 React.FC에서 허용되지 않는다.

const GenericComponent: React.FC</* ??? */> = <T>(props: GenericComponentProps<T>) => {/*...*/}

3. 네임 스페이스 패턴 이용시 더 불편하다.

다음과 같이 연관성 있는 컴포넌트에 대해서 네임 스페이스 패턴을 적용하는 방법이 있다.

<Select>
  <Select.Item />
</Select>

이를 FC를 사용할 때 물론 쓸 수는 있지만 매우 불편하다.

// FC를 사용할 때
const Select: React.FC<SelectProps> & { Item: React.FC<ItemProps> } = (
  props
) => {
  /* ... */
};
Select.Item = (props) => {
  /*...*/
};

// FC를 사용하지 않을 때
const Select = (props: SelectProps) => {
  /* ... */
};
Select.Item = (props: ItemProps) => {
  /*...*/
};

4. 코드가 길어진다.


그래서 어떻게 사용할까?

가장 일반적이고 간단한 방법은 props 옆에 타입을 정의해주는 것이다.

const C1: React.FC<CProps> = (props) => {}; // React.FC 사용
const C2 = (props: CProps) => {}; // 미사용

0개의 댓글