React - TypeScript

da.circle·2022년 12월 6일
0

TypeScript

목록 보기
5/7

리액트에 타입스크립트 적용하기

props에 대한 명세!

react-typescript-cheatsheet

객체 타입 정의

object

function myInfo(info: {name:string; pw:string}) {
	return console.log(info);
}
  • info의 타입은 재사용이 불가능하다.
  • 프로퍼티가 많을수록 가독성이 낮아진다.
  • state, props를 정의할 때는 interface나 type을 사용하는 것이 좋다.

type alias

type info = {
	name: string;
  	age: number;
}
  • type으로 정의한 info에 마우스 커서를 올리면 모든 프로퍼티가 나타난다.

interface

interface info {
	name: string;
  	age: number;
}
  • interface로 정의한 info에 마우스 커서를 올리면 interface명만 나타난다.
  • 복잡하게 정의되어있거나 재사용된 경우 사용하면 좋다.
  • 공식 문서에서는 type보다 interface를 사용할 것을 권장한다.
    type과 interface의 차이 - 공식문서


함수형 컴포넌트

FC타입

  • FunctionComponent 타입
  • 리액트에서 제공한다.
  • 줄여서 FC로 사용할 수 있다.
  • 제네릭으로 props 타입을 전달해야 한다.
interface InfoProps {
	name: string;
  	age: number;
}

const myInfo: React.FC<InfoProps> = ({info}) => {
	return (
    	<div>
      		{getInfo(info)}
      	</div>
    )
}

FC 정의
경로 ) node_modules/@types/react/index.d.ts

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

    interface FunctionComponent<P = {}> {
        (props: P, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P> | undefined;
        contextTypes?: ValidationMap<any> | undefined;
        defaultProps?: Partial<P> | undefined;
        displayName?: string | undefined;
    }
  • FC는 FunctionComponent 타입에 P를 제네릭으로 받았다.
    • 제네릭을 넘기지 않으면 빈 객체를 기본값으로 할당한다. (<P = {}>)
  • FunctionComponent는 제네릭 P를 넘겨받는 interface다.
    • (props: P, context?: any)를 제외한 나머지 프로퍼티는 선택적으로 할당할 수 있다.
  • props 파라미터를 받아서 ReactElement타입 또는 null을 반환한다.

ReactElement 정의

    interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }

	type Key = string | number;

JSXElementConstructor 정의

    type JSXElementConstructor<P> =
        | ((props: P) => ReactElement<any, any> | null)
        | (new (props: P) => Component<any, any>);

일반적인 함수 정의 방식

  • 함수형 컴포넌트는 곧 함수이다.
interface Info {
	age: number;
}

const myAge = ({age}: Info): JSX.Element => {
	return (
    	<div>
      		{getAge(age)}
      	</div>
    )
}
  • 함수형 컴포넌트는 props를 파라미터로 받고 JSX를 return한다.
  • JSX.Element는 타입추론이 되므로 생략이 가능하다.

Hooks

useState

const [check, setCheck] = useState(false);

setCheck(!check);
  • 특별히 타입을 지정하지 않아도 타입추론에 의해 타입이 지정된다.
  • check는 boolean타입, setCheck함수는 boolean타입만 인자로 받는다.
    • 다른 타입은 올 수 없다!

  • 타입을 직접 명시할 수도 있다.
    (초기값을 통해 타입을 알 수 있으므로 굳이 명시하지 않아도 될 것 같다는 생각이 든다)
const [check, setCheck] = useState<boolean>(false);

setCheck(!check)
  • state의 초기값으로 null을 사용하는 경우
    • 유니온 타입으로 타입을 명시한다.
const [check, setCheck] = useState<boolean | null>(null);

if(check){
 //로직~~
}

state에 객체가 포함된 경우

  • 자세한 프로퍼티 타입을 정의한다.
interface Comment {
	comment: string;
  	username: string;
  	date: string;
}

const [comments, setComments] = useState<Comment[]>([]);
  • comments 데이터는 아래와 같다.
    [
      {
        comment: "hi",
        username: "kim",
        date: "2022.12.05"
      },
      {
        comment: "hello~",
        username: "lee",
        date: "2022.12.06"
      }
    ]

useRef

  • useState처럼 타입을 명시하지 않아도 된다.
  • 타입을 명시하고 싶다면?
const divRef = useRef<HTMLDivElement>(null);

return(
	<>
		<ChildComponent divRef={divRef} />
		<div ref={divRef}>
			useRef에도 타입을 명시하고 싶습니다!
		</div>
	</>
)
  • HTMLDivElement : div용 타입
    • HTMLAnchorElement, HTMLButtonElement, HTMLTableElement 등 여러 타입이 있다.
  • <ChildComponent divRef={divRef} /> : 자식 컴포넌트에 props로 넘겨보았다.

Event Handler

  • 이벤트 핸들러 함수의 파라미터는 특별한 타입을 사용한다.
  • 명시하지 않아도 오류가 나지는 않는다.
  • 그래도 정확하게 이벤트 종류, 어떤 태그에서 사용하는지 명시해주는 것이 좋다.
const handleOnChange = (e: React.ChangeEvent<HTMLInputElement>) => {
	setEmail(e.target.value)
};

return <input onChange={handleOnChange}/>
  • handleOnChange 이벤트 핸들러는 e(event)를 파라미터로 받는다.
  • React.ChangeEvent : change이벤트에 사용하는 타입
  • input태그에서 발생하는 이벤트이므로 HTMLInputElement를 제네릭으로 넘겼다.
  • 일반적인 타입 이름 : 이벤트타입Event
    • ChangeEvent, FormEvent, TouchEvent, FocusEvent, KeyboardEvent, MouseEvent, DragEvent

JSX.Element

  • 변수에 JSX를 할당해 선언할 수 있다.
const tryAgainMessage: JSX.Element = <p>다시 시도해주세요.</p>

전역변수

  • window에 외부 라이브러리 변수를 추가하려면?
    • 해당 라이브러리에서 사용하는 전역 변수명을 추가한다.
    • window객체에 추가된 외부 라이브러리여도 타입을 정의하지않으면 에러가 뜬다.
//예시) 카카오 로그인을 위한 라이브러리 추가
declare global {
	interface Window {
    	kakao: any;
    }
}
profile
프론트엔드 개발자를 꿈꾸는 사람( •̀ ω •́ )✧

0개의 댓글