Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

타입스크립트로 리액트 컴포넌트 구성해보기 본문

🎨 프론트엔드/Typescript

타입스크립트로 리액트 컴포넌트 구성해보기

Chamming2 2021. 5. 21. 00:00

타입스크립트가 점점 프론트엔드 생태계에서의 입지를 굳혀가고 있는데요, 간단한 입력값을 상태로 관리하는 예제를 타입스크립트로 구성해보도록 하겠습니다.

😆 진짜 쉬워요! 타입스크립트를 끼얹기 전까진...

import React, { useState } from "react";

const App = () => {
  const [name, setName] = useState(null);

  const handleInput = (e) => {
     setName(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={handleInput}></input>
      <div>{name}</div>
    </div>
  );
};

export default App;

입력받는 값을 상태로 관리하고 화면에 나타내는 코드입니다.

이렇게만 보면 간단하지만 갑자기 타입스크립트를 얹게 되면 막막할 수도 있는데요, 위 코드에 차근차근 타입스크립트를 입혀보도록 하겠습니다.

1.  함수 컴포넌트의 생성

함수 컴포넌트를 생성할 때는 React.FC라는 타입을 사용합니다.

import React, { useState } from "react";

const App: React.FC = () => {
  const [name, setName] = useState(null);

  const handleInput = (e) => {
     setName(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={handleInput}></input>
      <div>{name}</div>
    </div>
  );
};

export default App;

React.FC 타입은 사용하지 않아도 오류를 출력하지 않으나 컴포넌트를 HOC로 활용하도록 해주는 children 속성을 가져옵니다.

React.FC를 사용했을 때 : children 속성이 제시되는 모습
React.FC를 사용하지 않으면 children 속성이 제시되지 않는다!

2.  속성의 타입 부여하기

속성(prop)의 타입을 부여하는 방법은 두 가지가 있습니다.

방법 1. React.FC의 제네릭으로 속성 타입 전달하기
type AppProps = {
  name?: string;
};

const App: React.FC<AppProps> = ({name}) => {
  return <div>{name}</div>
}

다만 이 방법은 React.FC가 없으면 사용할 수 없습니다.

그래서, 저는 제네릭을 사용하는 방법보다는 속성값 객체의 타입을 지정하는 방식이 더 낫다고 생각했습니다.

type AppProps = {
  name?: string;
};

const App = ({ name }: AppProps) => {
  return <div>{name}</div>
}

아쉽게도 저희가 만들고 있는 입력값을 출력하는 어플리케이션은 속성값을 받지 않고 있네요.

그냥 이렇게 하면 된다~ 만 짚고 넘어갑시다.

3. useState에 타입 부여하기

const [name, setName]: [string, any] = useState(null);

이름은 문자열 형태일테고, setName은 타입을 추론하기 어려우니 이렇게 타입을 지정하면 될까요?

물론 이러면 널 값을 문자열 타입에 대입할 수 없다고 출력되는데, 그럼 초기값으로 무조건 빈 문자열을 사용해야만 할까요?

const [name, setName]: [string | null, any] = useState(null);

아뇨~ '|' 기호를 활용해 유니온 타입을 활용할 수 있는데요, 이러면 문자열형 또는 널 타입을 name의 타입으로 활용할 수 있습니다.

import React, { useState } from "react";

const App: React.FC = () => {
  const [name, setName]: [string | null, any] = useState(null);

  const handleInput = (e) => {
     setName(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={handleInput}></input>
      <div>{name}</div>
    </div>
  );
};

export default App;

4. 이벤트 핸들러에 타입 부여하기

다음은 이벤트 핸들러인데요, 함수를 다룰 때는 두 가지의 타입을 신경써야 합니다. 바로 인자와 리턴값이죠.

const handleInput = (e) => {
   setName(e.target.value);
};

e가 객체인건 짐작이 되겠는데, 무슨 타입(인터페이스)의 객체일까요?

정답은 React.ChangeEvent<HTMLInputElement> 타입입니다.

 

이러면 다들 "아니 이걸 어떻게 알아요~" 라고 하실텐데, 이렇게 이벤트 위에 커서를 올리면 핸들러의 타입 정보를 얻을 수 있습니다.

핸들러의 타입이 React.ChangeEventHandler<HTML...> 임을 알았으니, 이걸 핸들러 함수의 타입으로 전달하겠습니다.

const handleInput: React.ChangeEventHandler<HTMLInputElement> = (e) => {
  setName(e.target.value);
};

(⚠️ 모든 핸들러와 이벤트 객체의 타입을 한번에 다 외우기는 어렵습니다. 이렇게 커서를 올렸을때 나타나는 타입 가이드를 자주 참고하세요!)

import React, { useState } from "react";

const App: React.FC = () => {
  const [name, setName]: [string | null, any] = useState(null);

  const handleInput: React.ChangeEventHandler<HTMLInputElement> = (e) => {
    setName(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={handleInput}></input>
      <div>{name}</div>
    </div>
  );
};

export default App;

놀랍겠지만 벌써 끝입니다! 😁

 

이론은 간단한 타입스크립트를 실제 프로젝트에 적용할 때는 분명 어려울 수도 있지만, 이렇게 간단한 코드부터 적용해보는 습관을 가지다 보면 (강하게 크다 보면) 어느샌가 새로운 도구에 익숙해진 여러분을 볼 수 있을거에요!

 

그럼, 오늘도 즐겁게 코드!

반응형
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆