티스토리 뷰

Vue&React

[React] React.FC<>

U_pic 2022. 7. 11. 18:19

나는 function Modal() {} 로서 컴포넌트를 선언하는 함수형 컴포넌트를 주로 사용해 왔다.

 

이번에 타입 스크립트를 사용을 연습하면서 React.FC라는 것을 처음 보게 되었다.

컴포넌트를 선언하면서 사용하게 되었는데 정확한 사용법을 알고 싶어서 이번 블로그 글을 작성하게 되었다.

 

FC 타입

React.FC는 함수형 컴포넌트의 타입을 선언할 때 사용한다.

React.FC <>와 같은 식으로 <> 안에 props에 대한 타입을 선언해줌으로써 사용할 수 있다.

interface Props {
	content: string
}

const Modal: React.FC<Props> = ({ content }) => (
	<div>{ content }</div>
)

 

FC 타입이 정의되어있는 코드를 보면

type FC<P = {}> = FunctionComponent<P>;

interface FunctionComponent<P = {}> {
  (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
  propTypes?: WeakValidationMap<P> | undefined;
  contextTypes?: ValidationMap<any> | undefined;
  defaultProps?: Partial<P> | undefined;
  displayName?: string | undefined;
}

기본적으로 FunctionComponent와 동일한 타입인 것을 알 수 있고,

props를 가지고 있는 ReactElement를 return하는 함수를 가지고 있는 것을 알 수 있다.

propsTypes, contextTypes, defaultProps, displayName과 같은 속성들도 추가하여 사용할 수 있다.

 

기존에 함수형 컴포넌트를 선언하는 방식과는 다른 점이 몇가지 존재한다.

 

1. defaultProps를 설정할 수 없다.

defaultProps는 클래스형 컴포넌트에서 쓰는 속성이었지만, props의 기본값을 설정하기 위해서 함수형 컴포넌트에서도 사용 가능하다.

하지만 React.FC에서는 내장 추가 속성으로 defaultProps를 가지기 때문에 외부에서 defaultProps를 설정하는 방식으로는 적용할 수 없다.

완전히 사용할 수 없진 않고, props의 인자들이 opitonal 하게 들어오는 경우에는 사용 가능했다.

import React from "react";
import "./App.css";

interface Props {
  content?: string;
}
const NameText: React.FC<Props> = ({ content }) => {
  return <h1>{content}</h1>;
};

NameText.defaultProps = {
  content: "Hello!",
};

function App() {
  return (
    <div className="App">
      <NameText />
    </div>
  );
}

export default App;

일반적인 함수형 컴포넌트에서는 다음과 같이 defaultProps를 설정할 수 있다.

import React from "react";
import "./App.css";

interface Props {
  content: string;
}
const NameText = ({ content }: Props) => {
  return <h1>{content}</h1>;
};

NameText.defaultProps = {
  content: "Hello!",
};

function App() {
  return (
    <div className="App">
      <NameText />
    </div>
  );
}

export default App;

 

 

2. chilren을 자유롭게 사용할 수 있다.

일반적인 함수형 컴포넌트 선언처럼 사용하면 하위 컴포넌트의 존재 여부에 대한 처리를 따로 해준 상태가 아니기 때문에 하위 컴포넌트를 선언했을 때 오류가 발생한다.

하지만 React.FC로 선언한 경우 children이 존재할 수 있기 때문에 하위 컴포넌트 가 존재해도 정상적으로 동작한다. Chilren을 가질 수 있다.

이 점을 활용해서 portal을 사용해서 modal을 제작하는 과정에서 portal 하위 컴포넌트로 modal 컴포넌트를 넣어야 했고, React.FC로 portal 컴포넌트를 선언해줌으로써 정상적으로 동작하는 컴포넌트를 만들 수 있었다.

import React from "react";
import { createPortal } from "react-dom";

const Portal: React.FC<{ isOpen: boolean }> = ({ isOpen, children }) => {
  if (!isOpen) return null;

  return createPortal(<div>{children}</div>, document.querySelector("#portal") as Element);
};

export default Portal;

하지만 다른 컴포넌트들은 일반적인 함수형 컴포넌트 선언 방식을 사용한 상태라

뭔가 코드 통일성을 해치는 코드가 아닐까 하는 생각이 문득 들었다.

최대한 기존 방식에서 children을 사용하는 방식을 찾았고, 아래와 같이 일반적인 함수형 컴포넌트 선언방식에서 children을 사용할 수 있게 코드를 변경해보았다.

import { PropsWithChildren } from "react";
import { createPortal } from "react-dom";

function Portal({ isOpen, children }: PropsWithChildren<{ isOpen: boolean }>) {
  if (!isOpen) return null;

  return createPortal(<div>{children}</div>, document.querySelector("#portal") as Element);
}

export default Portal;

 

### 정리

React.FC를 공부하면서 여러 글에서 React.FC사용을 지양하자는 의견들을 보았다.

React.FC가 기본적인 함수형 컴포넌트 선언 방식과 달리 내포하고 있는 기본적인 속성 + 추가적인 속성이 있다 보니

선택적으로 속성을 사용하다 보면 코드의 의도가 시각적으로 보이지 않을 수 있는 부분이 있겠다 하는 생각은 들었다.

 

기본적인 함수형 컴포넌트 선언방식으로도 충분히 React.FC에서 제공하는 속성을 사용할 수 있으니 사용하는 개발자의 선택에 달린 것이 분명한 문제인 것 같다. ( 너무 당연한 얘기인가요... ㅎㅎ )

 

### Reference

 

 

Home

yceffort

yceffort.kr

 

 

2. 리액트 컴포넌트 타입스크립트로 작성하기 · GitBook

2. 리액트 컴포넌트 타입스크립트로 작성하기 이번 섹션에서는 리액트 컴포넌트를 타입스크립트로 작성하는 방법을 알아보도록 하겠습니다. 프로젝트 생성 우선, 타입스크립트를 사용하는 리

react.vlpt.us

 

'Vue&React' 카테고리의 다른 글

[Vue.js] Sass 사용시 변수를 전역에서 사용하기  (0) 2022.07.25
[React] Image Preloading  (0) 2022.07.15
[React] Redux-Thunk로 비동기로직 처리하기  (0) 2022.05.16
[React] Modal with Portal  (0) 2022.05.10
Context API  (0) 2022.04.27
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함