React 타입스크립트의 개념과 사용법 정리

0

타입스크립트란?

타입스크립트는 언어의 기본 사용법과 문법은 자바스크립트와 동일하지만, 타입을 추가적으로 선언한다는 차이가 있습니다.

타입스크립트를 사용하면 동적인 자바스크립트의 변수를 정적으로 바꿔주기 때문에 타입스크립트 컴파일 과정에서 에러를 미리 잡아줄 수 있고, 에러에 대한 메세지가 구체적으로 자세하게 나오기 때문에 최근 프론트엔드 개발자들을 중심으로 선호되고 있는 추세라고 합니다.

React와 타입스크립트

React에 타입스크립트를 적용해서 사용하는 경우에도 기존의 React와 동일한 구조를 가져갈 수 있는데, state, props, function, event 등에 타입을 선언해준다는 점이 기존의 React와의 가장 큰 차이점이라고 할 수 있습니다.

State

state는 컴포넌트 내부에서 변경되고 사용되는 변수, 즉 “상태 값”을 말하는데, 이 상태 값들은 React 훅으로 관리됩니다.

state 사용법
const [changeSi, setChangeSi] = useState<boolean>(false);

다음의 코드 예제들과 같이 초기값을 설정해두는 경우에는 따로 타입을 선언하지 않아도 자동으로 타입을 추정해 줍니다.

상태가 null일 수도 있고 아닐수도 있는 경우
type Information = { name: string; description: string };
const [info, setInformation] = useState<Information | null>(null);
로그인 여부에 따라 userInfo의 값이 null이 될 수 있는 경우
export interface IUserInfo {
  userid: string | undefined;
  username: string | undefined;
}
const [userInfo, setUserInfo] = useState<IUserInfo | null>(null);
상태의 타입이 까다로운 구조를 가진 객체이거나 배열일 때
type Todo = { id: number; text: string; done: boolean };
const [todos, setTodos] = useState<Todo[]>([]);

참고로 배열인 경우에는 해당 배열이 어떤 타입으로 이루어진 배열인지 추론할 수 있도록 Generics을 명시하는 것이 좋습니다. 그리고 만약 다음과 같이 객체의 타입을 선언하는 경우에 타입이 반복 사용되는 경우라면 interfacetype을 이용하여 따로 생성해주는 것이 좋습니다.

interface
/* interface */
interface loc {
  title: string,
  y: number,
  x: number
}
/* type */
type loc = {
  title: string,
  y: number,
  x: number
}
const Store:React.FC =()=>{
  const [curLoc, setCurLoc] = React.useState<loc>();
  return(<></>)
}

Props

[props|code]는 컴포넌트 외부에서 받는 변수, 즉 “속성 값”을 말하는데, props는 컴포넌트 내부에서는 변경을 할 수 없습니다.

interface로 props 정의하기
interface props {
    storeId: number,
    setIsWrite: React.Dispatch<React.SetStateAction<boolean>>
}
const ReviewForm: React.FC<props> = ({ storeId, setIsWrite }) => {
  /*...*/
}

props는 컴포넌트에게 인자로 넘겨지는 값으로, React의 컴포넌트를 선언할 때 React.FC로 타입을 선언해주고 이 뒤에 props의 타입을 선언해주고, 받는 인자에 props를 선언해주면 됩니다. 이렇게 선언을 해주면 외부에서 잘못된 변수를 넘겨받았을 때 에러를 잡아줄 수 있습니다.

Function

React 함수에서도 타입스크립트 사용법은 비슷합니다. 즉 들어오는 인자의 타입을 선언해주고, 추가적으로 인자 뒤에 함수의 반환 타입까지 선언해줄 수 있습니다.

함수 타입 선언하기
const onClickFeature = (id: string) :void => {
  /*...*/
}

Event

React에서 타입스크립트를 적용하면서 가장 까다로운 부분이 바로 이벤트입니다. React의 요소에 어떤 타입을 선언할지 헷갈릴 수 있기 때문이죠.

input 이벤트 처리하기
const Feed :React.FC = () => {
  const [newNick, setNewNick] = useState({ nickName: "", valid: false, error: "" } as { nickName: string, valid: boolean, error: string });
  const onChangeNick = (event: React.ChangeEvent<HTMLInputElement>) => {
    setNewNick({ nickName: event.target.value, valid: true, error: "사용 가능" });
  }
  return (
    <form className="col-container" onSubmit={onSubmit}>
      <input type="text" value={newNick.nickName} onChange={onChangeNick} />
        <input type="submit" value="수정" />
    </form>)
}
export default Feed;

onChange의 경우 React.ChangeEvent<HTMLInputElement>로 이벤트가 사용되고, event.target.name, event.target.value 등으로 HTMLInputElement 속성 값을 사용할 수 있습니다.

타입 종류

자바스크립트에는 다음과 같은 원시 타입이 있습니다.

  • string
  • number
  • boolean
  • null
  • undefined
  • symbol
  • 객체(object , array)
타입스크립트로 타입 선언하기
interface Types{
  /*원시타입*/
  Primitives: string,
    Primitives2?: number,  //선언 필수 아님
  /*객체*/
  Object:{
    a: string,
    b: number,
  }
  /*배열*/
  Arr:{
    a: string,
    b: number,
  }[]
  Arr2:Object[]
}

interface 확장하기

interface가 여러 곳에서 반복 사용되거나 추가적으로 사용되는 경우에는 export하거나, 확장하여 사용할 수 있습니다.

interface 확장하기
//People.tsx
export interface PeopleInterface {
  name: string
  age: number
}

interface StudentInterface extends PeopleInterface {
  school: string
}

/* 외부 컴포넌트에서 가져오기 */
import PeopleInterface from "People.tsx";
const cmp:React.FC=()=>{
  const [people, setPeople]=useState<PeopleInterface>();
}

Leave a Reply