원문 : React with TypeScript: Components as Function Declarations vs. Function Expressions
타입스크립트를 처음 배우며 리액트에 사용하기 시작했을 때, 저는 패턴을 따랐습니다. 친구는 저에게 컴포넌트를 작성하는 방법을 보여주었고, 나는 새로운 컴포넌트를 만들 때 마다 이 방식을 사용했습니다.
const MyComponent: React.FC = () => <h1>Hello, world!</h1>
이 패턴을 사용하면서, function
키워드를 사용해서 컴포넌트를 선언하더라도 동일한 작업을 수행할 수 있으리라 생각했습니다.
function MyComponent(): React.FC {
return <h1>Hello, world!</h1>
}
React 컴포넌트를 함수 표현식으로 작성할 때(ex. const MyComponent: React.FC<Props>
),
MyComponent
가 가지는 값의 유형(타입) 은 무엇인지" 스스로 자문해야 합니다.
이 변수의 타입은 함수이므로, 함수 타입 으로 지정합니다. React.FC
는 "React Function Component"를 가르킵니다. 그렇기에 우리는 이러한 방식으로 입력하는 것입니다.
다른 경우에, 우리가 함수 선언문으로 React 컴포넌트를 작성할 때(ex. function MyComponent
) 우리는 같은걸 요구합니다.
이 경우 우리는 함수가 반환하는 값의 타입 을 지정합니다. 이것은 우리가 같은 유형(React.FC)을 사용할 수 없는 이유입니다. 우리는 대신 타입스크립트에게 "이 함수는 React 컴포넌트를 반환할거야!"라고 알려야합니다. 그럼 어떤 모습이 될까요?
function MyComponent(): React.ReactNode {
return <h1>Hello, world</h1>
}
이제, 타입스크립트는 이 함수가 ReactNode
타입의 무언가를 반환한다는 걸 알게 되었습니다. 만약 ReactNode
을 본 적이 없다면 @types/react
선언 파일에서 다음과 같은 union type임을 알 수 있습니다.
type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
이것들은 컴포넌트가 반환할 수 있는 모든 유효한 타입입니다. 이곳에서 소스 코드를 살펴보세요
이제 React 컴포넌트를 함수 선언문과 함수 표현식으로 표현하는 적절한 방법을 알게 되었습니다. 자세한 내용은 react-typescript-cheatsheet를 확인하세요.
컴포넌트가 props를 전달 받을 때, 해당 props가 추가되는 위치를 아는 것은 중요합니다.
type Props = {
name: string;
}
const MyComponent: React.FC<Props> = ({ name }) => <h1>Hello, {name}!</h1>
추가적으로, children
prop을 자동으로 포함하는 PropsWithChildren
라는 편리한 유형을 사용할 수 있습니다.
type Props = {
name: string;
}
const MyComponent: React.FC<PropsWithChildren<Props>> = ({ name, children }) => <h1>{children}, {name}!</h1>
우리는 함수 선언문으로도 같은 동작을 할 수 있습니다.
type Props = {
name: string;
}
function MyComponent({ name }: Props): React.ReactNode {
return <h1>Hello, {name}!</h1>
}
그리고 PropWithChildren
사용도 동일합니다
type Props = {
name: string;
}
function MyComponent({ name }: PropsWithChildren<Props>): React.ReactNode {
return <h1>{children}, {name}!</h1>
}
요점은 표현식은 "해당 변수가 컴포넌트(jsx)를 반환하는 함수"라는 걸 지정하고, (변수 자체에 집중)
선언식은 "해당 함수는 컴포넌트(jsx)를 반환한다는걸 지정하는 것 같다. (반환값에 집중)
결과가 달라진다기보다 타입스크립트가 검사하는 유형?이 다르다고 할까.. 함수 그 자체냐, 반환값이냐!