typescript useRef의 타입

antd+typescript+react를 사용하던 중 ref의 세 가지 타입에 대해 알게되어 포스팅한다.
react의 useRef는 세 가지 타입이 오버로딩 되어있다.

useRef

useRef는 initialValue를 useRef 객체의 current에 저장한다.
이 useRef의 current가 변경되어도 컴포넌트는 리렌더링 되지 않는다.
때문에 DOM 내부 객체를 직접 가리키거나 렌더링과 상관없는 변수를 저장하는데에 사용된다.

useRef의 타입

  1. MutableRefObject<T>
1
function useRef<T>(initialValue: T): MutableRefObject<T>;

initialValue의 타입과 제네릭의 타입이 T인경우 MutableRefObject<T>를 반환한다.
렌더링과 관련없는 값을 저장하는데에 사용하자.

  1. RefObject<T>
1
function useRef<T>(initialValue: T | null): RefObject<T>;

제네릭의 타입이 T이고 initialValue의 타입이 T 혹은 null인 경우 RefObject<T>를 반환한다.
RefObject<T>는 readonly로 current를 직접 수정할 수 없다.
하지만 current의 하위 프로퍼티는 조작 가능하다.

그렇기에 DOM 을 조작하기 위해 사용하자.

  1. MutableRefObject<T|undefined>
1
function useRef<T = undefined>(): MutableRefObject<T | undefined>;

ts+react에서 이벤트 객체의 타입 지정하기

ts+react를 사용할 때에 HTMLEvent의 타입을 지정하는 방법에 대해서 간단하게 정리해보았다.

React의 Event의 타입

Event의 타입은 React안에 정의되어있다.

onchange 이벤트의 타입은 React.ChangeEvent<T>이다.
onclick 이벤트의 경우 React.MouseEvent<T>이다.
제네릭에는 이벤트를 발생시키는 요소를 전달하면 된다.

예시

자주 쓰이는 useInput hooks이다.

이벤트의 타입을 React.ChangeEvent<HTMLInputElement>라고 명시해주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React, { useState, useCallback } from "react";

type UseInputTypes = [
string,
(e: React.ChangeEvent<HTMLInputElement>) => void,
React.Dispatch<React.SetStateAction<string>>
];
const useInput = (initialValue: string): UseInputTypes => {
const [value, setValue] = useState<string>(initialValue);

const onChangeValue = useCallback((e) => {
setValue(e.target.value);
}, []);
return [value, onChangeValue, setValue];
};

export default useInput;

typescript ReactElement ReactNode JSX.Element 차이

render

render() 함수는 다음 중 하나를 반환하여야한다.

  1. React Element
  • JSX를 사용하여 생성된다.
  1. 배열과 Fragment
  • render()를 통하여 여러개의 Element를 반환한다.
  1. Portal
  • 별도의 DOM 하위트리에 자식 엘리먼트를 렌더링한다.
  1. 문자열과 숫자
  • 이 값들은 DOM상에 텍스트 노드로서 렌더링된다.
  1. Boolean 또는 null
  • 아무것도 랜더링 하지 않는다.

render()는 순수한 함수여야 한다.
컴포넌트의 state를 변경하지 않고 호출될 때마다 동일한 결과를 반환해야한다.
또한 브라우저와 직접적으로 상호작용해서는 안된다.

ReactNode

ReactNode는 ReactChild 등등 많은 것을 포함한다.
제일 범용적으로 사용할 수 있는 것 같다..!(다른 관점에선 리펙토링 할 수 있는 부분)

클래스형 컴포넌트의 반환값이다!

1
2
3
4
5
6
7
type ReactNode =
| ReactChild
| ReactFragment
| ReactPortal
| boolean
| null
| undefined;

ReactElement

ReactElement는 type, props, 그리고 key를 가진 객체이다.

예전 게시글에서 알아본 것 처럼 함수형 컴포넌트의 반환값이다!

1
2
3
4
5
6
7
8
9
10
interface ReactElement<
P = any,
T extends string | JSXElementConstructor<any> =
| string
| JSXElementConstructor<any>
> {
type: T;
props: P;
key: Key | null;
}

JSX.Element

JSX.Element는 any type의 generic type인 ReactElement이다.
전역으로 선언되어있어 라이브러리들이 구현하여 사용할 수 있다.

1
2
declare global { namespace JSX { interface Element extends React.ReactElement<any, any> { }

++추가 React.FC

React.FCchildren이 포함되어있어 컴포넌트의 props의 타입 처리가 어렵다.

차라리 위의 ReactElementReactNode를 적용 후 children의 타입을 명시하는 것이 좋다..!