[ 번역 ] React with TypeScript: Components as Function Declarations vs. Function Expressions

DD·2021년 5월 21일
2

번역

목록 보기
9/10
post-thumbnail
post-custom-banner

원문 : React with TypeScript: Components as Function Declarations vs. Function Expressions

📣 이 글에 들어가기 전에

  • 해당 원문에서 annotate라는 동사가 자주 나오는데, 이는 타입스크립트에서 타입을 지정하는 행위를 말하는 것 같습니다.
  • 직역으로는 주석을 단다는 뜻이지만 이후 번역에서는 '타입을 지정하다' 라고 번역하겠습니다


타입스크립트를 처음 배우며 리액트에 사용하기 시작했을 때, 저는 패턴을 따랐습니다. 친구는 저에게 컴포넌트를 작성하는 방법을 보여주었고, 나는 새로운 컴포넌트를 만들 때 마다 이 방식을 사용했습니다.

const MyComponent: React.FC = () => <h1>Hello, world!</h1>

이 패턴을 사용하면서, function 키워드를 사용해서 컴포넌트를 선언하더라도 동일한 작업을 수행할 수 있으리라 생각했습니다.

function MyComponent(): React.FC {
	return <h1>Hello, world!</h1>
}

함수 표현식으로 React 컴포넌트 작성하기

React 컴포넌트를 함수 표현식으로 작성할 때(ex. const MyComponent: React.FC<Props>),

  • "우리가 타입으로 지정하는 React.FC<Props>가 무엇이며,
  • 변수 MyComponent가 가지는 값의 유형(타입) 은 무엇인지"

스스로 자문해야 합니다.

이 변수의 타입은 함수이므로, 함수 타입 으로 지정합니다. React.FC는 "React Function Component"를 가르킵니다. 그렇기에 우리는 이러한 방식으로 입력하는 것입니다.


함수 선언문으로 React 컴포넌트 작성하기

다른 경우에, 우리가 함수 선언문으로 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를 전달 받을 때, 해당 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>

함수 선언문으로 Props 유형 지정하기

우리는 함수 선언문으로도 같은 동작을 할 수 있습니다.

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)를 반환한다는걸 지정하는 것 같다. (반환값에 집중)

결과가 달라진다기보다 타입스크립트가 검사하는 유형?이 다르다고 할까.. 함수 그 자체냐, 반환값이냐!

profile
기억보단 기록을 / TIL 전용 => https://velog.io/@jjuny546
post-custom-banner

0개의 댓글