본문 바로가기
프론트엔드/TS 공부

HTML DOM + React 타입 정리

by 학습하는 청년 2024. 5. 24.

최종 수정 : 2024-05-24

HTML 타입

HTMLElement 타입

HTML<태그이름>Element 라는 이름으로 DOM 노드에 대한 타입을 사용할 수 있다.

const usernameInput = document.getElementById('username') as HTMLInputElement;
const submitButton = document.getElementById('submit') as HTMLButtonElement;

 

InputHTMLAttributes<HTML태그이름Element>

import { InputHTMLAttributes } from 'react';

interface Props extends InputHTMLAttributes<HTMLInputElement> {}

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

 

이벤트 타입

Event라는 타입을 쓸 수 있고, 구체적으로는 -Event로 끝나는 타입을 활용하면 된다.

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<노드타입> 형태의 타입을 상속해서 활용할 수 있다.

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[]>([]);

 

useEffect()는 타입을 작성하는 경우가 없다.

 

useRef()의 경우 대상이 되는 DOM 노드의 타입을 제네릭으로 지정하고, 초깃값으로 null을 지정해 주면 ref Props로 내려줄 때 타입 오류가 발생하지 않는다.

const formRef = useRef<HTMLFormElement>(null);

 

이벤트 핸들러

HTML 이벤트 타입과 마찬가지로 -Event로 끝나는 타입을 사용한다. 제네릭으로 DOM 노드 타입을 지정해 주면 이벤트 타겟의 타입을 지정할 수 있다. 이때 주의할 점은 react 패키지에서 불러와서 사용하는 타입이라는 점이다. 이름이 같은 이벤트들이 있으니 주의해야 한다. 어떤 이벤트인지 타입을 구체적으로 지정할 필요가 없다면 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

컨텍스트의 경우 컨텍스트 값의 타입을 제네릭으로 잘 지정해주면 된다. 초깃값도 올바로 지정해주면 된다.

type Locale = 'ko' | 'en';
interface LocaleContextValue {
  locale: Locale;
  setLocale: (value: Locale) => void;
}

const LocaleContext = createContext<LocaleContextValue>({
  locale: 'ko',
  setLocale: () => {},
});

 


https://www.codeit.kr/tutorials/90/%ED%83%80%EC%9E%85%20%EC%A0%95%EC%9D%98(d.ts)%20%ED%8C%8C%EC%9D%BC%EC%9D%B4%20%EB%AD%94%EA%B0%80%EC%9A%94%3F

댓글