[강의] React에 TypeScript 적용하기

김하은·2024년 1월 1일
0

코드잇 강의 정리

목록 보기
58/60

HTML 타입

HTMLElement 타입

  • HTML<태그이름>Element라는 이름으로 DOM 노드에 대한 타입을 사용할 수 있음
const usernameInput = document.getElementById('username') as HTMLInputElement;
const submitButton = document.getElementById('submit') as HTMLButtonElement;

이벤트 타입

  • 기본적으로는 Event라는 타입을 쓸 수 있음
  • 구체적으로는 -Event로 끝나는 타입을 활용하면 됨
  • 예를 들어서 oninput 이벤트에 대한 타입은 InputEvent이고, onclick 이벤트에 대한 타입은 MouseEvent
submitButton.addEventListener('click', handleClick);

function handleClick(e: MouseEvent) {
  e.preventDefault();
  const message = `${usernameInput.value}님 반갑습니다!`;
  alert(message);
}

React 타입

Props

  • 인터페이스를 사용해서 타입을 지정해 줌
  • children의 경우 ReactNode 라는 타입을 사용함
import { MouseEvent, ReactNode } from 'react';
import styles from './Button.module.css';

interface Props {
  className?: string;
  id?: string;
  children?: ReactNode;
  onClick: (e: MouseEvent<HTMLButtonElement>) => void;
}

const Button = ({ className = '', id, children, onClick }: Props) => {
  const classNames = `${styles.button} ${className}`;
  return (
    <button className={classNames} id={id} onClick={onClick}>
      {children}
    </button>
  );
}

export default Button;
  • HTML 기본 Props를 타입으로 정의하고 싶다면 태그이름HTMLAttributes<노드타입> 형태의 타입을 상속해서 활용할 수 있음
  • 예를 들어서 인풋 노드의 Props를 사용하고 싶다면 InputHTMLAttributes<HTMLInputElement>와 같이 씀
import { InputHTMLAttributes } from 'react';
import styles from './Input.module.css';

interface Props extends InputHTMLAttributes<HTMLInputElement> {
}

export default function Input({ className = '', ...rest }: Props) {
  const classNames = `${styles.input} ${className}`;
  return <input className={classNames} {...rest} />;
}

Hook

  • useState()의 경우 초깃값만 잘 지정하면 타입이 잘 추론됨
  • 기본값에서 타입이 추론되지 않으면 제네릭으로 타입을 지정해줌
  • 특히 빈 배열을 사용할 때 주의할 것
const names = useState<string[]>([]);
  • useRef()의 경우 대상이 되는 DOM 노드의 타입을 제네릭으로 지정하고, 초깃값으로 null을 지정해 주면, ref Props로 내려줄 때 타입 오류가 나지 않음
const formRef = useRef<HTMLFormElement>(null);

이벤트 핸들러

  • HTML 이벤트 타입과 마찬가지로 ChangeEvent, MouseEvent 같이 -Event로 끝나는 타입을 사용함
  • 제네릭으로 DOM 노드 타입을 지정해 주면 이벤트 타겟의 타입을 지정할 수 있음
  • 이때 주의할 점은 순수 HTML 자바스크립트에서 사용하는 MouseEvent가 아니라 react 패키지에서 불러와서 사용하는 MouseEvent 타입이라는 점으로 이름이 같은 이벤트들이 종종 있으니 주의할 것
  • 어떤 이벤트인지 타입을 구체적으로 지정할 필요가 없는 경우라면 SyntheticEvent라는 타입을 사용하면 됨
import { ChangeEvent, MouseEvent, useEffect, useRef, useState } from 'react';

// ...

function handleChange(e: ChangeEvent<HTMLInputElement>) {
    const { name, value } = e.target;
    const nextValues = {
      ...values,
      [name]: value,
    };
    setValues(nextValues);
  }

  function handleClick(e: MouseEvent<HTMLButtonElement>) {
  // function handleClick(e: SyntheticEvent)처럼 쓸 수도 있음
    e.preventDefault();

    const message = `${values.username}님 환영합니다`;
    alert(message);
  }

Context

  • 컨텍스트의 경우 컨텍스트 값의 타입을 제네릭으로 잘 지정해주면 ehla
  • 이때 초깃값도 올바로 지정할 것
type Locale = 'ko' | 'en';
interface LocaleContextValue {
  locale: Locale;
  setLocale: (value: Locale) => void;
}

const LocaleContext = createContext<LocaleContextValue>({
  locale: 'ko',
  setLocale: () => {},
});
profile
아이디어와 구현을 좋아합니다!

0개의 댓글