TypeScript + React로 함수형 컴포넌트를 개발하는 분들은 한번쯤은 '컴포넌트를 함수 표현식으로 개발할까? 함수 선언식으로 개발할까?', '타입을 명시하려고 타입스크립트를 사용하는거니까 React.FC 타입을 선언하는게 좋지 않을까?', 'React.FC 타입을 선언하는 것과 안하는 것의 차이가 있을까?' 궁금증을 가져보셨을 건데요.
이번 글에서는 위의 궁금증에 대한 대답을 간략하게 다뤄볼게요
함수형 컴포넌트를 개발할 때 다음과 같이 코드를 작성할 수 있습니다.
function Login() {
return (
<> .... </>
)
}
const Login = () => {
return (
<> .... </>
)
}
함수 선언식과 타입을 지정하지 않은 함수 표현식은 JSX.Element를 반환하는 함수를 타입으로 갖게 됩니다.


함수 표현식은 다음과 같이 React.FC 타입을 선언할 수도 있습니다.
const Login:React.FC = () => {
return (
<> .... </>
)
}

JSX.Element, JSX.Element가 상속받는 React.ReactElement, React.FC는 다음과 같이 정의되어 있습니다.
declare global { namespace JSX { interface Element extends React.ReactElement<any, any> {}
interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> { type: T; props: P; key: Key | null; }
type FC<P = {}> = FunctionComponent<P>; interface FunctionComponent<P = {}> { (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null; ... }
여기서 주목할 점은 JSX.Element가 상속받는 React.ReactElement와 FunctionComponent에 공통으로 들어있는 props 속성입니다.
ReactElement는 컴포넌트가 선언될 때의 props interface를 그대로 사용하고, FunctionComponent는 컴포넌트가 선언될 때의 props interface를 PropsWithChildren으로 감싸고 있는 것을 확인할 수 있습니다.
PropsWithChildren은 다음과 같이 정의되어 있습니다.
type PropsWithChildren<P> = P & { children?: ReactNode | undefined };
FunctionComponent가 PropsWithChildren을 통해서 props interface에 개발자가 정한 속성 외에 children 속성을 추가하는 것을 확인할 수 있습니다.
위의 내용을 확인할 간단한 React 코드입니다.
Main.tsx
...
import { default as FunctionalComponent } from './FunctionalComponent';
import { default as ChildComponent } from './ChildComponent';
function Main() {
return <FunctionalComponent>{ChildComponent}</FunctionalComponent>
}
FunctionalComponent.tsx
...
interface FunctionalComponentProps {
...
}
function FunctionalComponent(props: FunctionalComponentProps) {
return (
...
);
}

FunctionalComponent.tsx (React.FC Type)
...
interface FunctionalComponentProps {
...
}
const FunctionalComponent: React.FC<FunctionalComponentProps> = (props) => {
return (
...
);
};
