ReactNextCentral

함수 컴포넌트

Published on
타입스크립트와 리액트를 함께 사용할 때 함수 컴포넌트를 정의하는 방법과 `React.FC`와 `React.VFC`의 사용을 다루며 이들 간의 차이점과 권장 사용법을 설명합니다.

이들은 일반 함수처럼 props 인자를 받아 JSX 요소를 반환하는 형태로 작성될 수 있습니다.

// 프롭 타입 선언 - 더 많은 예시는 "컴포넌트 프롭스 타이핑"을 참고하세요.
type AppProps = {
  message: string;
}; /* 내보낼 때는 사용자가 확장할 수 있도록 `interface` 사용 */

// 함수 컴포넌트 선언의 가장 간단한 방법; 반환 타입은 추론됩니다.
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>;

// `React.FunctionComponent` (또는 `React.FC`)를 사용할 수도 있습니다. 
//최신 React 타입과 TypeScript 5.1 이후에는 대부분 스타일 선택이지만, 
// 그렇지 않을 경우 권장되지 않습니다.
const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

팁: Paul Shen의 VS Code 확장 프로그램을 사용하여 타입 구조 분해 선언을 자동화하고 (키보드 단축키 포함)할 수 있습니다.

React.FC가 필요하지 않나요? React.FunctionComponent/React.VoidFunctionComponent는 어떤가요?

많은 리액트+타입스크립트 코드베이스에서 다음과 같은 코드를 볼 수 있습니다.

const App: React.FunctionComponent<{ message: string }> = ({ message }) => (
  <div>{message}</div>
);

그러나 오늘날 일반적인 의견은 React.FunctionComponent (또는 축약형인 React.FC)가 필요하지 않다는 것입니다. React 17이나 TypeScript 5.1 미만을 사용하는 경우에는 권장되지 않습니다. 이것은 물론 미묘한 의견이지만, 동의하고 코드베이스에서 React.FC를 제거하고 싶다면, 이 jscodeshift codemod를 사용할 수 있습니다.

"일반 함수" 버전과의 몇 가지 차이점:

  • React.FunctionComponent는 반환 타입을 명시적으로 지정하는 반면, 일반 함수 버전은 암시적입니다(또는 추가적인 주석이 필요합니다).

  • displayName, propTypes, defaultProps와 같은 정적 속성에 대한 타입 검사와 자동 완성을 제공합니다.

    • React.FunctionComponent를 사용할 때 defaultProps와 관련된 몇 가지 알려진 문제가 있습니다. 자세한 내용은 이 문제를 참조하세요. 우리는 별도의 defaultProps 섹션도 유지 관리합니다.
  • React 18 타입 업데이트 이전에는, React.FunctionComponentchildren의 암시적 정의를 제공했는데, 이는 많은 논쟁의 대상이었으며 React.FC가 Create React App TypeScript 템플릿에서 제거된 이유 중 하나입니다.

// React 18 타입 이전
const Title: React.FunctionComponent<{ title: string }> = ({
  children,
  title,
}) => <div title={title}>{children}</div>;
(사용 중단) React.VoidFunctionComponent 또는 React.VFC 대신 사용하기

@types/react 16.9.48에서 children을 명시적으로 타이핑하기 위해 React.VoidFunctionComponent 또는 React.VFC 타입이 추가되었습니다. 하지만, React.VFCReact.VoidFunctionComponent는 React 18에서 사용 중단되었다는 점을 유의해주세요(참조). 그래서 이 임시 솔루션은 React 18+에서는 더 이상 필요하지 않거나 권장되지 않습니다.

대신 일반 함수 컴포넌트나 React.FC를 사용해주세요.

type Props = { foo: string };

// 지금은 괜찮지만, 미래에는 에러
const FunctionComponent: React.FunctionComponent<Props> = ({
  foo,
  children,
}: Props) => {
  return (
    <div>
      {foo} {children}
    </div>
  ); // 괜찮음
};

// 지금은 에러, 미래에는 사용 중단
const VoidFunctionComponent: React.VoidFunctionComponent<Props> = ({
  foo,
  children,
}) => {
  return (
    <div>
      {foo}
      {children}
    </div>
  );
};
  • 미래에 props를 자동으로 readonly로 표시할 수 있지만, 매개 변수 목록에서 props 객체가 구조 분해되는 경우에는 관련이 없습니다.

대부분의 경우 어떤 문법을 사용하든 큰 차이가 없지만, React.FunctionComponent의 명시적인 성격을 선호할 수도 있습니다.