Skip to content

[기술 공유] React.FC

Coa edited this page Mar 1, 2022 · 2 revisions

React.FC를 사용하면 children과 함께 잘 동작합니다.

// Works as expected:
const MyComponent: React.FC<MyComponentProps> = function ({
  className,
  children,
}) {
  // children is typed
  return <div className={className}>{children}</div>;
};

이것은 React.FC가 children 속성을 props type에 추가하기 때문입니다. 이것은 편리해 보이지만, 실제로는 나쁜 것입니다! React.FC를 사용하면 항상 children을 속성으로 취하는 것 처럼 보입니다.

type MyComponentProps = { title: string };
const MyComponent: React.FC<MyComponentProps> = function ({ title }) {
  // children이 지정되지 않았기 때문에 TypeScript가 이를 지적합니다.
  return <div>{title}</div>;
};

// TypeScript는 이를 허용하지만, 이것은 어떤 의미에서는 '오탐'입니다.
const myValue = <MyComponent title="Hello">{ children}</MyComponent>;

// This is more correct
function MyComponentCorrect({ title }: MyComponentProps) {
  return <div>{title}</div>;
}

const myValueCorrect = (
  <MyComponentCorrect title="Hello">{ children}</MyComponentCorrect>
);
// Error:
// Type '{ children: string; title: string; }' is not assignable to type 'IntrinsicAttributes & MyComponentProps'.
//   Property 'children' does not exist on type 'IntrinsicAttributes & MyComponentProps'.

파라미터에 직접 타입을 지정하는 것은 오탐을 허용하지 않고 더 많은 유연성, 정확성을 제공합니다. 그렇다면 어떻게 children의 타입을 지정할까요? 두 가지 방법이 있습니다.

  • 수동으로 직접
  • React의 helper types 사용
// Manually
type MyComponentProps = {
  title: string;
  // ReactNode 는 배열, fragments, scalar 값 등을 포함하는 모든 자식 타입입니다.
  children: React.ReactNode;
};

function MyComponentCorrect({ title, children }: MyComponentProps) {}

만약 children에 어떤 유형을 사용할지 기억하기 어렵다면, React types로부터 편리한 helper를 사용할 수 있습니다.

type MyComponentProps = React.PropsWithChildren<{
  title: string;
}>;

function MyComponentCorrect({ title, children }: MyComponentProps) {}

같은 일을 합니다. PropsWithChildren은 React.FC처럼 intersection type으로 정의됩니다.

type PropsWithChildren<P> = P & { children?: ReactNode };
// (note: optional type is redundant as ReactNode can be undefined)

기존 TypeScript 관용 관례를 보아야한다고 생각합니다. 기본 관행은 generics와 같은 공통 기능을 혼동 없이 허용해야합니다.

  • 타입 지정에 있어서 일관성을 유지하고,
  • 호이스팅과 직접 default exports하기를 더 허용하며
  • children에 대한 오탐을 피하고
  • generics을 지원하며
  • React 컴포넌트의 props 타입을 항상 함수의 매개변수로 직접 지정하기를 권합니다.

하지만 새로운 컴포넌트를 작성함에 있어 파라미터에 직접 타입을 지정하고 코드베이스에서 점차 React.FC 를 제거해가는 건 확실히 가치가 있다고 생각합니다.

TypeScript React.FC confusion

Short list of React.FC cons:

  1. Provides an implicit definition of children, even if your component doesn't need to have children. That might cause an error.
  2. Doesn't support generics.
  3. Doesn't work correctly with defaultProps.

React.FC 단점:

구성 요소에 자식이 필요하지 않더라도 자식에 대한 암시적 정의를 제공합니다. 그러면 오류가 발생할 수 있습니다. 제네릭을 지원하지 않습니다. defaultProps에서 올바르게 작동하지 않습니다.

Best solution:

The second approach + a return type

const PrintName2 = ({ prop1, prop2 }: Props): JSX.Element => { /** */}

This gives you complete control over the Props and is more explicit (there is no hidden magic).

Link to GitHub PR to remove React.FC

Kent C Dodds has some thoughts why this is here

https://stackoverflow.com/questions/68027985/is-nextpage-necessary-when-building-nextjs-apps-in-typescript

📝 팀 규칙

🐛 트러블 슈팅

Test 관련 이슈
Next.js 관련 이슈
React 관련 이슈
Git 관련 이슈
기타 이슈

🧑‍💻 개발

기술공유
  • 레퍼런스
  • 📆 회의록

    데일리
    Clone this wiki locally