React.FC
는 React + TypeScript에서 자주 사용되는 함수형 컴포넌트 선언 방법 중 하나입니다. 하지만React.FC
사용에 대해 개발자들 사이에서 자주 논란이 발생하고 있고, 'React.FC
사용을 자제하자'로 결론이 모아지고 있다고 합니다.
이번 포스트에서는 어떤 부분 때문에 그러한 결론이 나왔는지 자세히 알아보고자 합니다.
React와 TypeScript를 사용하는 환경에서 함수형 컴포넌트를 선언하는 방법에는 여러 가지가 있습니다. 각각의 차이점에 대해 알아봅시다.
먼저, prop의 타입을 선언합니다.
type AppProps = {
message: string;
}
✅ 타입을 확장할 수 있도록 내보낼 때는(export) interface
를 사용하세요. interface와 type의 차이점을 알고 싶다면 여기를 클릭하세요.
const App = ({ message }: AppProps) => <div>{message}</div>;
const App = ({ message }: AppProps): React.JSX.Element => <div>{message}</div>;
const App = ({ message }: { message: string }) => <div>{message}</div>;
const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
<div>{message}</div>
);
React.FunctionComponent
(줄여서 React.FC
)를 사용할 수 있습니다.React 17이나 TypeScript 5.1 이하 버전을 사용하고 있다면 권장하지 않습니다.
(1) React.FC
는 리턴 타입을 명시하지만, 일반 함수는 타입을 암시합니다. (또는 추가로 타입을 지정해야 합니다.)
type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
(props: P, context?: any): ReactNode;
propTypes?: WeakValidationMap<P> | undefined;
contextTypes?: ValidationMap<any> | undefined;
defaultProps?: Partial<P> | undefined;
displayName?: string | undefined;
}
node_modules/@types/react/index.d.ts
파일에서 React.FC
가 가지고 있는 타입들을 살펴볼 수 있습니디.React.FC
는 타입을 명시하고 있습니다.(2) displayName
, propTypes
, defaultProps
처럼 정적 프로퍼티들에 대해 타입 체크와 자동완성을 제공합니다.
React.FC
는 정적 프로퍼티들에 대해 타입 체크와 자동완성을 지원합니다.React.FC
에서 defaultProps
의 사용에 대한 이슈가 끊이지 않고 있습니다. React.FC
에서 defaultProps
는 선택 사항(optional)으로 설정되고 LibraryManagedAttributes
가 중단되어 코드가 원하는대로 작동하지 않습니다.LibraryManagedAttributes
는 컴포넌트의 props
타입에 대한 변환을 정의합니다.(3) React 18 타입 업데이트 이전, React.FC
는 children
에 대해 암시적인 정의를 제공했는데(아래 참고), 이는 많은 논란이 있었고 이것이 Create React App TypeScript 탬플릿에서 React.FC
가 제거된 이유 중 하나입니다.
// React 18 이전
const Title: React.FunctionComponent<{ title: string }> => ({
children, // Error
title, // Error
}) => <div title={title}>{children}</div>;
Binding element 'children'('title') implicitly has an 'any' type.ts(7031)
에러가 발생합니다.children(title)
의 타입이 암시적으로 any
타입이 할당되어 발생한 에러입니다. props
객체가 매개변수에서 구조분해 되었기 때문입니다.React.FC
를 에러없이 사용하려면 children
에 직접 타입을 지정해주어야 합니다.React.FC
사용을 권장하지 않습니다.참고
🔗 Function Components: https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components/
🔗 React.FC에 대한 issue: https://github.com/typescript-cheatsheets/react/issues/87
🔗 LibraryManagedAttributes: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html