tech.junha.kr

[React+Typescript] React.FC를 굳이 사용하지 않아도 되는 이유

1. 코드 가독성

const Greeting:FC<GreetingProps> = function({ name }) {
  return <h1>Hello {name}</h1>
}
function Greeting({ name }: GreetingProps) {
  return <h1>Hello {name}</h1>
}

굳이 FC type을 명시해줘서 코드 가독성이 떨어진다.

2. FC<> always imply children

export const Greeting:FC<GreetingProps> = ({ name }) => {
  // name is string!
  return <h1>Hello {name}</h1>
};

// use it in the app
const App = () => <>
  <Greeting name="Stefan">
    <span>{"I can set this element but it doesn't do anything"}</span>
  </Greeting>
</>

React.FC는 암묵적으로 children prop을 내장하고 있기 때문에 위와 같이 children prop을 지정하지 않더라도 위 코드는 오류없이 동작한다.

function Greeting({ name }: GreetingProps) {
  return <h1>Hello {name}</h1>
}
const App = () => <>
  <Greeting name="Stefan">
    {/* The next line throws errors at me! ?*/}
    <span>{"I can set this element but it doesn't do anything"}</span>
  </Greeting>
</>

이런 경우는 helper Type을 사용하여 컴포넌트에 prop을 추가하여 사용한다.

type WithChildren<T = {}> =
  T & { children?: React.ReactNode };

type CardProps = WithChildren<{
  title: string
}>

function Card({ title, children }: CardProps) {
  return <>
    <h1>{ title }</h1>
    {children}
  </>
}

이유는 특정 컴포넌트에서는 children 필요 할수도 하지 않을 수도 있는데, React.FC 는 children 을 옵셔널 타입으로 지정해놨기에 이는 타입스크립트의 철학과는 모호한 관계를 띄게 된다.

따라서 특정 컴포넌트에서 children 을 필요로 한다면 반드시 children 타입을 명시해야한다.
react.fc를 사용하면 children을 명시해야 하기 때문에 props결과 적으로 차라리, React.FC 를 사용하지 않고 GreetingsProps 타입을 통해 children이 있다 없다를 명백하게 명시하는게 덜 헷갈린다.

defaultProps

defaultProps는 class기반 React에서 prop의 default값을 지정해주기 위해 사용한다.

type LoginMsgProps = {
    name?: string;
    };

function LoginMsg({ name = "Guest" }: LoginMsgProps) {
    return <p>Logged in as {name}</p>;
    }

하지만 React.FC는 defaultProps를 연결을 끊고 props으로 들어온 기본값으로 사용한다.

export const Greeting:FC<GreetingProps> = ({ name }) => {
    // name is string!
    return <h1>Hello {name}</h1>
};

Greeting.defaultProps = { name: "World" };

const App = () =>
    <>
    {/* Big boom ?*/}
    <Greeting />
   </>

React.FC 사용하지 않는다면 오류없이 사용할 수 있다.

export const Greeting = ({ name }: GreetingProps) => {
    // name is string!
    return <h1>Hello {name}</h1>
};

Greeting.defaultProps = { name: "World" };

const App = () =>
    <>
        {/* Yes! ✅ */}
        <Greeting />
    </>